581c6a6c2bcd26d84f4e8788e3dd66320a38a25c
[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               /* The object is still available.  Add the reference now.  */
133               if (__builtin_expect (act >= undef_map->l_reldepsmax, 0))
134                 {
135                   /* Allocate more memory for the dependency list.  Since
136                      this can never happen during the startup phase we can
137                      use `realloc'.  */
138                   void *newp;
139
140                   undef_map->l_reldepsmax += 5;
141                   newp = realloc (undef_map->l_reldeps,
142                                   undef_map->l_reldepsmax
143                                   * sizeof(struct link_map *));
144
145                   if (__builtin_expect (newp != NULL, 1))
146                     undef_map->l_reldeps = (struct link_map **) newp;
147                   else
148                     /* Correct the addition.  */
149                     undef_map->l_reldepsmax -= 5;
150                 }
151
152               /* If we didn't manage to allocate memory for the list this
153                  is no fatal mistake.  We simply increment the use counter
154                  of the referenced object and don't record the dependencies.
155                  This means this increment can never be reverted and the
156                  object will never be unloaded.  This is semantically the
157                  correct behaviour.  */
158               if (__builtin_expect (act < undef_map->l_reldepsmax, 1))
159                 undef_map->l_reldeps[undef_map->l_reldepsact++] = map;
160
161               /* And increment the counter in the referenced object.  */
162               ++map->l_opencount;
163
164               /* Display information if we are debugging.  */
165               if (__builtin_expect (_dl_debug_files, 0))
166                 _dl_debug_message (1, "\nfile=",
167                                    map->l_name[0] ? map->l_name : _dl_argv[0],
168                                    ";  needed by ",
169                                    undef_map->l_name[0]
170                                    ? undef_map->l_name : _dl_argv[0],
171                                    " (relocation dependency)\n\n", NULL);
172             }
173           else
174             /* Whoa, that was bad luck.  We have to search again.  */
175             result = -1;
176         }
177     }
178
179   /* Release the lock.  */
180   __libc_lock_unlock (_dl_load_lock);
181
182   return result;
183 }
184
185
186 /* Search loaded objects' symbol tables for a definition of the symbol
187    UNDEF_NAME.  */
188
189 lookup_t
190 internal_function
191 _dl_lookup_symbol (const char *undef_name, struct link_map *undef_map,
192                    const ElfW(Sym) **ref, struct r_scope_elem *symbol_scope[],
193                    int reloc_type, int explicit)
194 {
195   const char *reference_name = undef_map ? undef_map->l_name : NULL;
196   const unsigned long int hash = _dl_elf_hash (undef_name);
197   struct sym_val current_value = { NULL, NULL };
198   struct r_scope_elem **scope;
199   int protected;
200   int noexec = elf_machine_lookup_noexec_p (reloc_type);
201   int noplt = elf_machine_lookup_noplt_p (reloc_type);
202
203   ++_dl_num_relocations;
204
205   /* Search the relevant loaded objects for a definition.  */
206   for (scope = symbol_scope; *scope; ++scope)
207     if (do_lookup (undef_name, hash, *ref, &current_value, *scope, 0, NULL,
208                    noexec, noplt))
209       {
210         /* We have to check whether this would bind UNDEF_MAP to an object
211            in the global scope which was dynamically loaded.  In this case
212            we have to prevent the latter from being unloaded unless the
213            UNDEF_MAP object is also unloaded.  */
214         if (__builtin_expect (current_value.m->l_global, 0)
215             && (__builtin_expect (current_value.m->l_type, lt_library)
216                 == lt_loaded)
217             && undef_map != current_value.m
218             /* Don't do this for explicit lookups as opposed to implicit
219                runtime lookups.  */
220             && __builtin_expect (! explicit, 1)
221             /* Add UNDEF_MAP to the dependencies.  */
222             && add_dependency (undef_map, current_value.m) < 0)
223           /* Something went wrong.  Perhaps the object we tried to reference
224              was just removed.  Try finding another definition.  */
225           return _dl_lookup_symbol (undef_name, undef_map, ref, symbol_scope,
226                                     reloc_type, 0);
227
228         break;
229       }
230
231   if (__builtin_expect (current_value.s == NULL, 0))
232     {
233       if (*ref == NULL || ELFW(ST_BIND) ((*ref)->st_info) != STB_WEAK)
234         /* We could find no value for a strong reference.  */
235         /* XXX We cannot translate the messages.  */
236         _dl_signal_cerror (0, (reference_name && reference_name[0]
237                                ? reference_name
238                                : (_dl_argv[0] ?: "<main program>")),
239                            make_string (undefined_msg, undef_name));
240       *ref = NULL;
241       return 0;
242     }
243
244   protected = *ref && ELFW(ST_VISIBILITY) ((*ref)->st_other) == STV_PROTECTED;
245
246   if (__builtin_expect (_dl_debug_bindings, 0))
247     _dl_debug_message (1, "binding file ",
248                        (reference_name && reference_name[0]
249                         ? reference_name
250                         : (_dl_argv[0] ?: "<main program>")),
251                        " to ", current_value.m->l_name[0]
252                        ? current_value.m->l_name : _dl_argv[0],
253                        ": ", protected ? "protected" : "normal",
254                        " symbol `", undef_name, "'\n", NULL);
255
256   if (__builtin_expect (protected == 0, 1))
257     {
258       *ref = current_value.s;
259       return LOOKUP_VALUE (current_value.m);
260     }
261   else
262     {
263       /* It is very tricky. We need to figure out what value to
264          return for the protected symbol */
265       struct sym_val protected_value = { NULL, NULL };
266
267       for (scope = symbol_scope; *scope; ++scope)
268         if (do_lookup (undef_name, hash, *ref, &protected_value, *scope, 0,
269                        NULL, 0, 1))
270           break;
271
272       if (protected_value.s == NULL || protected_value.m == undef_map)
273         {
274           *ref = current_value.s;
275           return LOOKUP_VALUE (current_value.m);
276         }
277
278       return LOOKUP_VALUE (undef_map);
279     }
280 }
281
282
283 /* This function is nearly the same as `_dl_lookup_symbol' but it
284    skips in the first list all objects until SKIP_MAP is found.  I.e.,
285    it only considers objects which were loaded after the described
286    object.  If there are more search lists the object described by
287    SKIP_MAP is only skipped.  */
288 lookup_t
289 internal_function
290 _dl_lookup_symbol_skip (const char *undef_name,
291                         struct link_map *undef_map, const ElfW(Sym) **ref,
292                         struct r_scope_elem *symbol_scope[],
293                         struct link_map *skip_map)
294 {
295   const char *reference_name = undef_map ? undef_map->l_name : NULL;
296   const unsigned long int hash = _dl_elf_hash (undef_name);
297   struct sym_val current_value = { NULL, NULL };
298   struct r_scope_elem **scope;
299   size_t i;
300   int protected;
301
302   ++_dl_num_relocations;
303
304   /* Search the relevant loaded objects for a definition.  */
305   scope = symbol_scope;
306   for (i = 0; (*scope)->r_duplist[i] != skip_map; ++i)
307     assert (i < (*scope)->r_nduplist);
308
309   if (i >= (*scope)->r_nlist
310          || ! do_lookup (undef_name, hash, *ref, &current_value, *scope, i,
311                          skip_map, 0, 0))
312     while (*++scope)
313       if (do_lookup (undef_name, hash, *ref, &current_value, *scope, 0,
314                      skip_map, 0, 0))
315         break;
316
317   if (__builtin_expect (current_value.s == NULL, 0))
318     {
319       *ref = NULL;
320       return 0;
321     }
322
323   protected = *ref && ELFW(ST_VISIBILITY) ((*ref)->st_other) == STV_PROTECTED;
324
325   if (__builtin_expect (_dl_debug_bindings, 0))
326     _dl_debug_message (1, "binding file ",
327                        (reference_name && reference_name[0]
328                         ? reference_name
329                         : (_dl_argv[0] ?: "<main program>")),
330                        " to ", current_value.m->l_name[0]
331                        ? current_value.m->l_name : _dl_argv[0],
332                        ": ", protected ? "protected" : "normal",
333                        " symbol `", undef_name, "'\n", NULL);
334
335   if (__builtin_expect (protected == 0, 1))
336     {
337       *ref = current_value.s;
338       return LOOKUP_VALUE (current_value.m);
339     }
340   else
341     {
342       /* It is very tricky.  We need to figure out what value to
343          return for the protected symbol.  */
344       struct sym_val protected_value = { NULL, NULL };
345
346       if (i >= (*scope)->r_nlist
347           || !do_lookup (undef_name, hash, *ref, &protected_value, *scope, i,
348                          skip_map, 0, 1))
349         while (*++scope)
350           if (do_lookup (undef_name, hash, *ref, &protected_value, *scope, 0,
351                          skip_map, 0, 1))
352             break;
353
354       if (protected_value.s == NULL || protected_value.m == undef_map)
355         {
356           *ref = current_value.s;
357           return LOOKUP_VALUE (current_value.m);
358         }
359
360       return LOOKUP_VALUE (undef_map);
361     }
362 }
363
364
365 /* This function works like _dl_lookup_symbol but it takes an
366    additional arguement with the version number of the requested
367    symbol.
368
369    XXX We'll see whether we need this separate function.  */
370 lookup_t
371 internal_function
372 _dl_lookup_versioned_symbol (const char *undef_name,
373                              struct link_map *undef_map, const ElfW(Sym) **ref,
374                              struct r_scope_elem *symbol_scope[],
375                              const struct r_found_version *version,
376                              int reloc_type, int explicit)
377 {
378   const char *reference_name = undef_map ? undef_map->l_name : NULL;
379   const unsigned long int hash = _dl_elf_hash (undef_name);
380   struct sym_val current_value = { NULL, NULL };
381   struct r_scope_elem **scope;
382   int protected;
383   int noexec = elf_machine_lookup_noexec_p (reloc_type);
384   int noplt = elf_machine_lookup_noplt_p (reloc_type);
385
386   ++_dl_num_relocations;
387
388   /* Search the relevant loaded objects for a definition.  */
389   for (scope = symbol_scope; *scope; ++scope)
390     {
391       int res = do_lookup_versioned (undef_name, hash, *ref, &current_value,
392                                      *scope, 0, version, NULL, noexec, noplt);
393       if (res > 0)
394         {
395           /* We have to check whether this would bind UNDEF_MAP to an object
396              in the global scope which was dynamically loaded.  In this case
397              we have to prevent the latter from being unloaded unless the
398              UNDEF_MAP object is also unloaded.  */
399           if (__builtin_expect (current_value.m->l_global, 0)
400               && (__builtin_expect (current_value.m->l_type, lt_library)
401                   == lt_loaded)
402               && undef_map != current_value.m
403               /* Don't do this for explicit lookups as opposed to implicit
404                  runtime lookups.  */
405               && __builtin_expect (! explicit, 1)
406               /* Add UNDEF_MAP to the dependencies.  */
407               && add_dependency (undef_map, current_value.m) < 0)
408             /* Something went wrong.  Perhaps the object we tried to reference
409                was just removed.  Try finding another definition.  */
410             return _dl_lookup_versioned_symbol (undef_name, undef_map, ref,
411                                                 symbol_scope, version,
412                                                 reloc_type, 0);
413
414           break;
415         }
416
417       if (__builtin_expect (res, 0) < 0)
418         {
419           /* Oh, oh.  The file named in the relocation entry does not
420              contain the needed symbol.  */
421           /* XXX We cannot translate the message.  */
422           _dl_signal_cerror (0, (reference_name && reference_name[0]
423                                  ? reference_name
424                                  : (_dl_argv[0] ?: "<main program>")),
425                              make_string ("symbol ", undef_name, ", version ",
426                                           version->name,
427                                           " not defined in file ",
428                                           version->filename,
429                                           " with link time reference",
430                                           res == -2
431                                           ? " (no version symbols)" : ""));
432           *ref = NULL;
433           return 0;
434         }
435     }
436
437   if (__builtin_expect (current_value.s == NULL, 0))
438     {
439       if (*ref == NULL || ELFW(ST_BIND) ((*ref)->st_info) != STB_WEAK)
440         /* We could find no value for a strong reference.  */
441         /* XXX We cannot translate the message.  */
442         _dl_signal_cerror (0, (reference_name && reference_name[0]
443                                ? reference_name
444                                : (_dl_argv[0] ?: "<main program>")),
445                            make_string (undefined_msg, undef_name,
446                                         ", version ", version->name ?: NULL));
447       *ref = NULL;
448       return 0;
449     }
450
451   protected = *ref && ELFW(ST_VISIBILITY) ((*ref)->st_other) == STV_PROTECTED;
452
453   if (__builtin_expect (_dl_debug_bindings, 0))
454     _dl_debug_message (1, "binding file ",
455                        (reference_name && reference_name[0]
456                         ? reference_name
457                         : (_dl_argv[0] ?: "<main program>")),
458                        " to ", current_value.m->l_name[0]
459                        ? current_value.m->l_name : _dl_argv[0],
460                        ": ", protected ? "protected" : "normal",
461                        " symbol `", undef_name, "' [", version->name,
462                        "]\n", NULL);
463
464   if (__builtin_expect (protected == 0, 1))
465     {
466       *ref = current_value.s;
467       return LOOKUP_VALUE (current_value.m);
468     }
469   else
470     {
471       /* It is very tricky. We need to figure out what value to
472          return for the protected symbol */
473       struct sym_val protected_value = { NULL, NULL };
474
475       for (scope = symbol_scope; *scope; ++scope)
476         if (do_lookup_versioned (undef_name, hash, *ref, &protected_value,
477                                  *scope, 0, version, NULL, 0, 1))
478           break;
479
480       if (protected_value.s == NULL || protected_value.m == undef_map)
481         {
482           *ref = current_value.s;
483           return LOOKUP_VALUE (current_value.m);
484         }
485
486       return LOOKUP_VALUE (undef_map);
487     }
488 }
489
490
491 /* Similar to _dl_lookup_symbol_skip but takes an additional argument
492    with the version we are looking for.  */
493 lookup_t
494 internal_function
495 _dl_lookup_versioned_symbol_skip (const char *undef_name,
496                                   struct link_map *undef_map,
497                                   const ElfW(Sym) **ref,
498                                   struct r_scope_elem *symbol_scope[],
499                                   const struct r_found_version *version,
500                                   struct link_map *skip_map)
501 {
502   const char *reference_name = undef_map ? undef_map->l_name : NULL;
503   const unsigned long int hash = _dl_elf_hash (undef_name);
504   struct sym_val current_value = { NULL, NULL };
505   struct r_scope_elem **scope;
506   size_t i;
507   int protected;
508
509   ++_dl_num_relocations;
510
511   /* Search the relevant loaded objects for a definition.  */
512   scope = symbol_scope;
513   for (i = 0; (*scope)->r_duplist[i] != skip_map; ++i)
514     assert (i < (*scope)->r_nduplist);
515
516   if (i >= (*scope)->r_nlist
517       || ! do_lookup_versioned (undef_name, hash, *ref, &current_value,
518                                 *scope, i, version, skip_map, 0, 0))
519     while (*++scope)
520       if (do_lookup_versioned (undef_name, hash, *ref, &current_value, *scope,
521                                0, version, skip_map, 0, 0))
522         break;
523
524   if (__builtin_expect (current_value.s == NULL, 0))
525     {
526       if (*ref == NULL || ELFW(ST_BIND) ((*ref)->st_info) != STB_WEAK)
527         {
528           /* We could find no value for a strong reference.  */
529           const size_t len = strlen (undef_name);
530           char buf[sizeof undefined_msg + len];
531           __mempcpy (__mempcpy (buf, undefined_msg, sizeof undefined_msg - 1),
532                      undef_name, len + 1);
533           /* XXX We cannot translate the messages.  */
534           _dl_signal_cerror (0, (reference_name && reference_name[0]
535                                  ? reference_name
536                                  : (_dl_argv[0] ?: "<main program>")), buf);
537         }
538       *ref = NULL;
539       return 0;
540     }
541
542   protected = *ref && ELFW(ST_VISIBILITY) ((*ref)->st_other) == STV_PROTECTED;
543
544   if (__builtin_expect (_dl_debug_bindings, 0))
545     _dl_debug_message (1, "binding file ",
546                        (reference_name && reference_name[0]
547                         ? reference_name
548                         : (_dl_argv[0] ?: "<main program>")),
549                        " to ", current_value.m->l_name[0]
550                        ? current_value.m->l_name : _dl_argv[0],
551                        ": ", protected ? "protected" : "normal",
552                        " symbol `", undef_name, "' [", version->name,
553                        "]\n", NULL);
554
555   if (__builtin_expect (protected == 0, 1))
556     {
557       *ref = current_value.s;
558       return LOOKUP_VALUE (current_value.m);
559     }
560   else
561     {
562       /* It is very tricky. We need to figure out what value to
563          return for the protected symbol */
564       struct sym_val protected_value = { NULL, NULL };
565
566       if (i >= (*scope)->r_nlist
567           || !do_lookup_versioned (undef_name, hash, *ref, &protected_value,
568                                    *scope, i, version, skip_map, 0, 1))
569         while (*++scope)
570           if (do_lookup_versioned (undef_name, hash, *ref, &protected_value,
571                                    *scope, 0, version, skip_map, 0, 1))
572             break;
573
574       if (protected_value.s == NULL || protected_value.m == undef_map)
575         {
576           *ref = current_value.s;
577           return LOOKUP_VALUE (current_value.m);
578         }
579
580       return LOOKUP_VALUE (undef_map);
581     }
582 }
583
584
585 /* Cache the location of MAP's hash table.  */
586
587 void
588 internal_function
589 _dl_setup_hash (struct link_map *map)
590 {
591   Elf_Symndx *hash;
592   Elf_Symndx nchain;
593
594   if (!map->l_info[DT_HASH])
595     return;
596   hash = (void *)(map->l_addr + map->l_info[DT_HASH]->d_un.d_ptr);
597
598   map->l_nbuckets = *hash++;
599   nchain = *hash++;
600   map->l_buckets = hash;
601   hash += map->l_nbuckets;
602   map->l_chain = hash;
603 }