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