No need to manipulate l_opencount anymore.
[kopensolaris-gnu/glibc.git] / elf / dl-lookup.c
1 /* Look up a symbol in the loaded objects.
2    Copyright (C) 1995-2002, 2003, 2004, 2005 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 <libintl.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <unistd.h>
25 #include <ldsodefs.h>
26 #include "dl-hash.h"
27 #include <dl-machine.h>
28 #include <bits/libc-lock.h>
29 #include <tls.h>
30
31 #include <assert.h>
32
33 #define VERSTAG(tag)    (DT_NUM + DT_THISPROCNUM + DT_VERSIONTAGIDX (tag))
34
35 /* We need this string more than once.  */
36 static const char undefined_msg[] = "undefined symbol: ";
37
38
39 struct sym_val
40   {
41     const ElfW(Sym) *s;
42     struct link_map *m;
43   };
44
45
46 #define make_string(string, rest...) \
47   ({                                                                          \
48     const char *all[] = { string, ## rest };                                  \
49     size_t len, cnt;                                                          \
50     char *result, *cp;                                                        \
51                                                                               \
52     len = 1;                                                                  \
53     for (cnt = 0; cnt < sizeof (all) / sizeof (all[0]); ++cnt)                \
54       len += strlen (all[cnt]);                                               \
55                                                                               \
56     cp = result = alloca (len);                                               \
57     for (cnt = 0; cnt < sizeof (all) / sizeof (all[0]); ++cnt)                \
58       cp = __stpcpy (cp, all[cnt]);                                           \
59                                                                               \
60     result;                                                                   \
61   })
62
63 /* Statistics function.  */
64 #ifdef SHARED
65 # define bump_num_relocations() ++GL(dl_num_relocations)
66 #else
67 # define bump_num_relocations() ((void) 0)
68 #endif
69
70
71 /* The actual lookup code.  */
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   struct link_map *runp;
82   unsigned int act;
83   unsigned int i;
84   int result = 0;
85
86   /* Avoid self-references and references to objects which cannot be
87      unloaded anyway.  */
88   if (undef_map == map)
89     return 0;
90
91   /* Make sure nobody can unload the object while we are at it.  */
92   __rtld_lock_lock_recursive (GL(dl_load_lock));
93
94   /* Avoid references to objects which cannot be unloaded anyway.  */
95   if (map->l_type != lt_loaded
96       || (map->l_flags_1 & DF_1_NODELETE) != 0)
97     goto out;
98
99   /* If the object with the undefined reference cannot be removed ever
100      just make sure the same is true for the object which contains the
101      definition.  */
102   if (undef_map->l_type != lt_loaded
103       || (undef_map->l_flags_1 & DF_1_NODELETE) != 0)
104     {
105       map->l_flags_1 |= DF_1_NODELETE;
106       goto out;
107     }
108
109   /* Determine whether UNDEF_MAP already has a reference to MAP.  First
110      look in the normal dependencies.  */
111   if (undef_map->l_searchlist.r_list != NULL)
112     {
113       list = undef_map->l_initfini;
114
115       for (i = 0; list[i] != NULL; ++i)
116         if (list[i] == map)
117           goto out;
118     }
119
120   /* No normal dependency.  See whether we already had to add it
121      to the special list of dynamic dependencies.  */
122   list = undef_map->l_reldeps;
123   act = undef_map->l_reldepsact;
124
125   for (i = 0; i < act; ++i)
126     if (list[i] == map)
127       goto out;
128
129   /* The object is not yet in the dependency list.  Before we add
130      it make sure just one more time the object we are about to
131      reference is still available.  There is a brief period in
132      which the object could have been removed since we found the
133      definition.  */
134   runp = GL(dl_ns)[undef_map->l_ns]._ns_loaded;
135   while (runp != NULL && runp != map)
136     runp = runp->l_next;
137
138   if (runp != NULL)
139     {
140       /* The object is still available.  Add the reference now.  */
141       if (__builtin_expect (act >= undef_map->l_reldepsmax, 0))
142         {
143           /* Allocate more memory for the dependency list.  Since this
144              can never happen during the startup phase we can use
145              `realloc'.  */
146           void *newp;
147
148           undef_map->l_reldepsmax += 5;
149           newp = realloc (undef_map->l_reldeps,
150                           undef_map->l_reldepsmax
151                           * sizeof (struct link_map *));
152
153           if (__builtin_expect (newp != NULL, 1))
154             undef_map->l_reldeps = (struct link_map **) newp;
155           else
156             /* Correct the addition.  */
157             undef_map->l_reldepsmax -= 5;
158         }
159
160       /* If we didn't manage to allocate memory for the list this is
161          no fatal mistake.  We simply increment the use counter of the
162          referenced object and don't record the dependencies.  This
163          means this increment can never be reverted and the object
164          will never be unloaded.  This is semantically the correct
165          behavior.  */
166       if (__builtin_expect (act < undef_map->l_reldepsmax, 1))
167         undef_map->l_reldeps[undef_map->l_reldepsact++] = map;
168
169       /* Display information if we are debugging.  */
170       if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_FILES, 0))
171         _dl_debug_printf ("\
172 \nfile=%s [%lu];  needed by %s [%lu] (relocation dependency)\n\n",
173                           map->l_name[0] ? map->l_name : rtld_progname,
174                           map->l_ns,
175                           undef_map->l_name[0]
176                           ? undef_map->l_name : rtld_progname,
177                           undef_map->l_ns);
178     }
179   else
180     /* Whoa, that was bad luck.  We have to search again.  */
181     result = -1;
182
183  out:
184   /* Release the lock.  */
185   __rtld_lock_unlock_recursive (GL(dl_load_lock));
186
187   return result;
188 }
189
190 static void
191 internal_function
192 _dl_debug_bindings (const char *undef_name, struct link_map *undef_map,
193                     const ElfW(Sym) **ref, struct r_scope_elem *symbol_scope[],
194                     struct sym_val *value,
195                     const struct r_found_version *version, int type_class,
196                     int protected);
197
198
199 /* Search loaded objects' symbol tables for a definition of the symbol
200    UNDEF_NAME, perhaps with a requested version for the symbol.  */
201 lookup_t
202 internal_function
203 _dl_lookup_symbol_x (const char *undef_name, struct link_map *undef_map,
204                      const ElfW(Sym) **ref,
205                      struct r_scope_elem *symbol_scope[],
206                      const struct r_found_version *version,
207                      int type_class, int flags, struct link_map *skip_map)
208 {
209   const unsigned long int hash = _dl_elf_hash (undef_name);
210   struct sym_val current_value = { NULL, NULL };
211   struct r_scope_elem **scope = symbol_scope;
212
213   bump_num_relocations ();
214
215   /* No other flag than DL_LOOKUP_ADD_DEPENDENCY is allowed if we look
216      up a versioned symbol.  */
217   assert (version == NULL || flags == 0 || flags == DL_LOOKUP_ADD_DEPENDENCY);
218
219   size_t i = 0;
220   if (__builtin_expect (skip_map != NULL, 0))
221     {
222       /* Search the relevant loaded objects for a definition.  */
223       while ((*scope)->r_list[i] != skip_map)
224         ++i;
225
226       assert (i < (*scope)->r_nlist);
227     }
228
229   /* Search the relevant loaded objects for a definition.  */
230   for (size_t start = i; *scope != NULL; start = 0, ++scope)
231     {
232       int res = do_lookup_x (undef_name, hash, *ref, &current_value, *scope,
233                              start, version, flags, skip_map, type_class);
234       if (res > 0)
235         break;
236
237       if (__builtin_expect (res, 0) < 0 && skip_map == NULL)
238         {
239           /* Oh, oh.  The file named in the relocation entry does not
240              contain the needed symbol.  This code is never reached
241              for unversioned lookups.  */
242           assert (version != NULL);
243           const char *reference_name = undef_map ? undef_map->l_name : NULL;
244
245           /* XXX We cannot translate the message.  */
246           _dl_signal_cerror (0, (reference_name[0]
247                                  ? reference_name
248                                  : (rtld_progname ?: "<main program>")),
249                              N_("relocation error"),
250                              make_string ("symbol ", undef_name, ", version ",
251                                           version->name,
252                                           " not defined in file ",
253                                           version->filename,
254                                           " with link time reference",
255                                           res == -2
256                                           ? " (no version symbols)" : ""));
257           *ref = NULL;
258           return 0;
259         }
260     }
261
262   if (__builtin_expect (current_value.s == NULL, 0))
263     {
264       if ((*ref == NULL || ELFW(ST_BIND) ((*ref)->st_info) != STB_WEAK)
265           && skip_map == NULL)
266         {
267           /* We could find no value for a strong reference.  */
268           const char *reference_name = undef_map ? undef_map->l_name : "";
269           const char *versionstr = version ? ", version " : "";
270           const char *versionname = (version && version->name
271                                      ? version->name : "");
272
273           /* XXX We cannot translate the message.  */
274           _dl_signal_cerror (0, (reference_name[0]
275                                  ? reference_name
276                                  : (rtld_progname ?: "<main program>")),
277                              N_("symbol lookup error"),
278                              make_string (undefined_msg, undef_name,
279                                           versionstr, versionname));
280         }
281       *ref = NULL;
282       return 0;
283     }
284
285   int protected = (*ref
286                    && ELFW(ST_VISIBILITY) ((*ref)->st_other) == STV_PROTECTED);
287   if (__builtin_expect (protected != 0, 0))
288     {
289       /* It is very tricky.  We need to figure out what value to
290          return for the protected symbol.  */
291       if (type_class == ELF_RTYPE_CLASS_PLT)
292         {
293           if (current_value.s != NULL && current_value.m != undef_map)
294             {
295               current_value.s = *ref;
296               current_value.m = undef_map;
297             }
298         }
299       else
300         {
301           struct sym_val protected_value = { NULL, NULL };
302
303           for (scope = symbol_scope; *scope != NULL; i = 0, ++scope)
304             if (do_lookup_x (undef_name, hash, *ref, &protected_value,
305                              *scope, i, version, flags, skip_map,
306                              ELF_RTYPE_CLASS_PLT) != 0)
307               break;
308
309           if (protected_value.s != NULL && protected_value.m != undef_map)
310             {
311               current_value.s = *ref;
312               current_value.m = undef_map;
313             }
314         }
315     }
316
317   /* We have to check whether this would bind UNDEF_MAP to an object
318      in the global scope which was dynamically loaded.  In this case
319      we have to prevent the latter from being unloaded unless the
320      UNDEF_MAP object is also unloaded.  */
321   if (__builtin_expect (current_value.m->l_type == lt_loaded, 0)
322       /* Don't do this for explicit lookups as opposed to implicit
323          runtime lookups.  */
324       && (flags & DL_LOOKUP_ADD_DEPENDENCY) != 0
325       /* Add UNDEF_MAP to the dependencies.  */
326       && add_dependency (undef_map, current_value.m) < 0)
327       /* Something went wrong.  Perhaps the object we tried to reference
328          was just removed.  Try finding another definition.  */
329       return _dl_lookup_symbol_x (undef_name, undef_map, ref,
330                                   symbol_scope, version, type_class,
331                                   flags, skip_map);
332
333   /* The object is used.  */
334   current_value.m->l_used = 1;
335
336   if (__builtin_expect (GLRO(dl_debug_mask)
337                         & (DL_DEBUG_BINDINGS|DL_DEBUG_PRELINK), 0))
338     _dl_debug_bindings (undef_name, undef_map, ref, symbol_scope,
339                         &current_value, version, type_class, protected);
340
341   *ref = current_value.s;
342   return LOOKUP_VALUE (current_value.m);
343 }
344
345
346 /* Cache the location of MAP's hash table.  */
347
348 void
349 internal_function
350 _dl_setup_hash (struct link_map *map)
351 {
352   Elf_Symndx *hash;
353   Elf_Symndx nchain;
354
355   if (!map->l_info[DT_HASH])
356     return;
357   hash = (void *) D_PTR (map, l_info[DT_HASH]);
358
359   map->l_nbuckets = *hash++;
360   nchain = *hash++;
361   map->l_buckets = hash;
362   hash += map->l_nbuckets;
363   map->l_chain = hash;
364 }
365
366
367 static void
368 internal_function
369 _dl_debug_bindings (const char *undef_name, struct link_map *undef_map,
370                     const ElfW(Sym) **ref, struct r_scope_elem *symbol_scope[],
371                     struct sym_val *value,
372                     const struct r_found_version *version, int type_class,
373                     int protected)
374 {
375   const char *reference_name = undef_map->l_name;
376
377   if (GLRO(dl_debug_mask) & DL_DEBUG_BINDINGS)
378     {
379       _dl_debug_printf ("binding file %s [%lu] to %s [%lu]: %s symbol `%s'",
380                         (reference_name[0]
381                          ? reference_name
382                          : (rtld_progname ?: "<main program>")),
383                         undef_map->l_ns,
384                         value->m->l_name[0] ? value->m->l_name : rtld_progname,
385                         value->m->l_ns,
386                         protected ? "protected" : "normal", undef_name);
387       if (version)
388         _dl_debug_printf_c (" [%s]\n", version->name);
389       else
390         _dl_debug_printf_c ("\n");
391     }
392 #ifdef SHARED
393   if (GLRO(dl_debug_mask) & DL_DEBUG_PRELINK)
394     {
395       int conflict = 0;
396       struct sym_val val = { NULL, NULL };
397
398       if ((GLRO(dl_trace_prelink_map) == NULL
399            || GLRO(dl_trace_prelink_map) == GL(dl_ns)[LM_ID_BASE]._ns_loaded)
400           && undef_map != GL(dl_ns)[LM_ID_BASE]._ns_loaded)
401         {
402           const unsigned long int hash = _dl_elf_hash (undef_name);
403
404           do_lookup_x (undef_name, hash, *ref, &val,
405                        undef_map->l_local_scope[0], 0, version, 0, NULL,
406                        type_class);
407
408           if (val.s != value->s || val.m != value->m)
409             conflict = 1;
410         }
411
412 # ifdef USE_TLS
413       if (value->s
414           && (__builtin_expect (ELFW(ST_TYPE) (value->s->st_info)
415                                 == STT_TLS, 0)))
416         type_class = 4;
417 # endif
418
419       if (conflict
420           || GLRO(dl_trace_prelink_map) == undef_map
421           || GLRO(dl_trace_prelink_map) == NULL
422           || type_class == 4)
423         {
424           _dl_printf ("%s 0x%0*Zx 0x%0*Zx -> 0x%0*Zx 0x%0*Zx ",
425                       conflict ? "conflict" : "lookup",
426                       (int) sizeof (ElfW(Addr)) * 2,
427                       (size_t) undef_map->l_map_start,
428                       (int) sizeof (ElfW(Addr)) * 2,
429                       (size_t) (((ElfW(Addr)) *ref) - undef_map->l_map_start),
430                       (int) sizeof (ElfW(Addr)) * 2,
431                       (size_t) (value->s ? value->m->l_map_start : 0),
432                       (int) sizeof (ElfW(Addr)) * 2,
433                       (size_t) (value->s ? value->s->st_value : 0));
434
435           if (conflict)
436             _dl_printf ("x 0x%0*Zx 0x%0*Zx ",
437                         (int) sizeof (ElfW(Addr)) * 2,
438                         (size_t) (val.s ? val.m->l_map_start : 0),
439                         (int) sizeof (ElfW(Addr)) * 2,
440                         (size_t) (val.s ? val.s->st_value : 0));
441
442           _dl_printf ("/%x %s\n", type_class, undef_name);
443         }
444     }
445 #endif
446 }