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