Remove .cvsignore files
[glibc-ports.git] / sysdeps / mips / dl-lookup.c
blob015c153d18379006429bcf65a9c7dc80882f01cf
1 /* Look up a symbol in the loaded objects.
2 MIPS/Linux version - this is identical to the common version, but
3 because it is in sysdeps/mips, it gets sysdeps/mips/do-lookup.h.
4 Using <do-lookup.h> instead of "do-lookup.h" would work too.
6 Copyright (C) 1995-2005, 2006, 2007 Free Software Foundation, Inc.
7 This file is part of the GNU C Library.
9 The GNU C Library is free software; you can redistribute it and/or
10 modify it under the terms of the GNU Lesser General Public
11 License as published by the Free Software Foundation; either
12 version 2.1 of the License, or (at your option) any later version.
14 The GNU C Library is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 Lesser General Public License for more details.
19 You should have received a copy of the GNU Lesser General Public
20 License along with the GNU C Library; if not, write to the Free
21 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
22 02111-1307 USA. */
24 #include <alloca.h>
25 #include <libintl.h>
26 #include <stdlib.h>
27 #include <string.h>
28 #include <unistd.h>
29 #include <ldsodefs.h>
30 #include <dl-hash.h>
31 #include <dl-machine.h>
32 #include <sysdep-cancel.h>
33 #include <bits/libc-lock.h>
34 #include <tls.h>
36 #include <assert.h>
38 #define VERSTAG(tag) (DT_NUM + DT_THISPROCNUM + DT_VERSIONTAGIDX (tag))
40 /* We need this string more than once. */
41 static const char undefined_msg[] = "undefined symbol: ";
44 struct sym_val
46 const ElfW(Sym) *s;
47 struct link_map *m;
51 #define make_string(string, rest...) \
52 ({ \
53 const char *all[] = { string, ## rest }; \
54 size_t len, cnt; \
55 char *result, *cp; \
57 len = 1; \
58 for (cnt = 0; cnt < sizeof (all) / sizeof (all[0]); ++cnt) \
59 len += strlen (all[cnt]); \
61 cp = result = alloca (len); \
62 for (cnt = 0; cnt < sizeof (all) / sizeof (all[0]); ++cnt) \
63 cp = __stpcpy (cp, all[cnt]); \
65 result; \
68 /* Statistics function. */
69 #ifdef SHARED
70 # define bump_num_relocations() ++GL(dl_num_relocations)
71 #else
72 # define bump_num_relocations() ((void) 0)
73 #endif
76 /* The actual lookup code. */
77 #include "do-lookup.h"
80 static uint_fast32_t
81 dl_new_hash (const char *s)
83 uint_fast32_t h = 5381;
84 for (unsigned char c = *s; c != '\0'; c = *++s)
85 h = h * 33 + c;
86 return h & 0xffffffff;
90 /* Add extra dependency on MAP to UNDEF_MAP. */
91 static int
92 internal_function
93 add_dependency (struct link_map *undef_map, struct link_map *map, int flags)
95 struct link_map *runp;
96 unsigned int i;
97 int result = 0;
99 /* Avoid self-references and references to objects which cannot be
100 unloaded anyway. */
101 if (undef_map == map)
102 return 0;
104 /* Avoid references to objects which cannot be unloaded anyway. */
105 assert (map->l_type == lt_loaded);
106 if ((map->l_flags_1 & DF_1_NODELETE) != 0)
107 return 0;
109 struct link_map_reldeps *l_reldeps
110 = atomic_forced_read (undef_map->l_reldeps);
112 /* Make sure l_reldeps is read before l_initfini. */
113 atomic_read_barrier ();
115 /* Determine whether UNDEF_MAP already has a reference to MAP. First
116 look in the normal dependencies. */
117 struct link_map **l_initfini = atomic_forced_read (undef_map->l_initfini);
118 if (l_initfini != NULL)
120 for (i = 0; l_initfini[i] != NULL; ++i)
121 if (l_initfini[i] == map)
122 return 0;
125 /* No normal dependency. See whether we already had to add it
126 to the special list of dynamic dependencies. */
127 unsigned int l_reldepsact = 0;
128 if (l_reldeps != NULL)
130 struct link_map **list = &l_reldeps->list[0];
131 l_reldepsact = l_reldeps->act;
132 for (i = 0; i < l_reldepsact; ++i)
133 if (list[i] == map)
134 return 0;
137 /* Save serial number of the target MAP. */
138 unsigned long long serial = map->l_serial;
140 /* Make sure nobody can unload the object while we are at it. */
141 if (__builtin_expect (flags & DL_LOOKUP_GSCOPE_LOCK, 0))
143 /* We can't just call __rtld_lock_lock_recursive (GL(dl_load_lock))
144 here, that can result in ABBA deadlock. */
145 THREAD_GSCOPE_RESET_FLAG ();
146 __rtld_lock_lock_recursive (GL(dl_load_lock));
147 /* While MAP value won't change, after THREAD_GSCOPE_RESET_FLAG ()
148 it can e.g. point to unallocated memory. So avoid the optimizer
149 treating the above read from MAP->l_serial as ensurance it
150 can safely dereference it. */
151 map = atomic_forced_read (map);
153 /* From this point on it is unsafe to dereference MAP, until it
154 has been found in one of the lists. */
156 /* Redo the l_initfini check in case undef_map's l_initfini
157 changed in the mean time. */
158 if (undef_map->l_initfini != l_initfini
159 && undef_map->l_initfini != NULL)
161 l_initfini = undef_map->l_initfini;
162 for (i = 0; l_initfini[i] != NULL; ++i)
163 if (l_initfini[i] == map)
164 goto out_check;
167 /* Redo the l_reldeps check if undef_map's l_reldeps changed in
168 the mean time. */
169 if (undef_map->l_reldeps != NULL)
171 if (undef_map->l_reldeps != l_reldeps)
173 struct link_map **list = &undef_map->l_reldeps->list[0];
174 l_reldepsact = undef_map->l_reldeps->act;
175 for (i = 0; i < l_reldepsact; ++i)
176 if (list[i] == map)
177 goto out_check;
179 else if (undef_map->l_reldeps->act > l_reldepsact)
181 struct link_map **list
182 = &undef_map->l_reldeps->list[0];
183 i = l_reldepsact;
184 l_reldepsact = undef_map->l_reldeps->act;
185 for (; i < l_reldepsact; ++i)
186 if (list[i] == map)
187 goto out_check;
191 else
192 __rtld_lock_lock_recursive (GL(dl_load_lock));
194 /* The object is not yet in the dependency list. Before we add
195 it make sure just one more time the object we are about to
196 reference is still available. There is a brief period in
197 which the object could have been removed since we found the
198 definition. */
199 runp = GL(dl_ns)[undef_map->l_ns]._ns_loaded;
200 while (runp != NULL && runp != map)
201 runp = runp->l_next;
203 if (runp != NULL)
205 /* The object is still available. */
207 /* MAP could have been dlclosed, freed and then some other dlopened
208 library could have the same link_map pointer. */
209 if (map->l_serial != serial)
210 goto out_check;
212 /* Redo the NODELETE check, as when dl_load_lock wasn't held
213 yet this could have changed. */
214 if ((map->l_flags_1 & DF_1_NODELETE) != 0)
215 goto out;
217 /* If the object with the undefined reference cannot be removed ever
218 just make sure the same is true for the object which contains the
219 definition. */
220 if (undef_map->l_type != lt_loaded
221 || (undef_map->l_flags_1 & DF_1_NODELETE) != 0)
223 map->l_flags_1 |= DF_1_NODELETE;
224 goto out;
227 /* Add the reference now. */
228 if (__builtin_expect (l_reldepsact >= undef_map->l_reldepsmax, 0))
230 /* Allocate more memory for the dependency list. Since this
231 can never happen during the startup phase we can use
232 `realloc'. */
233 struct link_map_reldeps *newp;
234 unsigned int max
235 = undef_map->l_reldepsmax ? undef_map->l_reldepsmax * 2 : 10;
237 newp = malloc (sizeof (*newp) + max * sizeof (struct link_map *));
238 if (newp == NULL)
240 /* If we didn't manage to allocate memory for the list this is
241 no fatal problem. We simply make sure the referenced object
242 cannot be unloaded. This is semantically the correct
243 behavior. */
244 map->l_flags_1 |= DF_1_NODELETE;
245 goto out;
247 else
249 if (l_reldepsact)
250 memcpy (&newp->list[0], &undef_map->l_reldeps->list[0],
251 l_reldepsact * sizeof (struct link_map *));
252 newp->list[l_reldepsact] = map;
253 newp->act = l_reldepsact + 1;
254 atomic_write_barrier ();
255 void *old = undef_map->l_reldeps;
256 undef_map->l_reldeps = newp;
257 undef_map->l_reldepsmax = max;
258 if (old)
259 _dl_scope_free (old);
262 else
264 undef_map->l_reldeps->list[l_reldepsact] = map;
265 atomic_write_barrier ();
266 undef_map->l_reldeps->act = l_reldepsact + 1;
269 /* Display information if we are debugging. */
270 if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_FILES, 0))
271 _dl_debug_printf ("\
272 \nfile=%s [%lu]; needed by %s [%lu] (relocation dependency)\n\n",
273 map->l_name[0] ? map->l_name : rtld_progname,
274 map->l_ns,
275 undef_map->l_name[0]
276 ? undef_map->l_name : rtld_progname,
277 undef_map->l_ns);
279 else
280 /* Whoa, that was bad luck. We have to search again. */
281 result = -1;
283 out:
284 /* Release the lock. */
285 __rtld_lock_unlock_recursive (GL(dl_load_lock));
287 if (__builtin_expect (flags & DL_LOOKUP_GSCOPE_LOCK, 0))
288 THREAD_GSCOPE_SET_FLAG ();
290 return result;
292 out_check:
293 if (map->l_serial != serial)
294 result = -1;
295 goto out;
298 static void
299 internal_function
300 _dl_debug_bindings (const char *undef_name, struct link_map *undef_map,
301 const ElfW(Sym) **ref, struct sym_val *value,
302 const struct r_found_version *version, int type_class,
303 int protected);
306 /* Search loaded objects' symbol tables for a definition of the symbol
307 UNDEF_NAME, perhaps with a requested version for the symbol.
309 We must never have calls to the audit functions inside this function
310 or in any function which gets called. If this would happen the audit
311 code might create a thread which can throw off all the scope locking. */
312 lookup_t
313 internal_function
314 _dl_lookup_symbol_x (const char *undef_name, struct link_map *undef_map,
315 const ElfW(Sym) **ref,
316 struct r_scope_elem *symbol_scope[],
317 const struct r_found_version *version,
318 int type_class, int flags, struct link_map *skip_map)
320 const uint_fast32_t new_hash = dl_new_hash (undef_name);
321 unsigned long int old_hash = 0xffffffff;
322 struct sym_val current_value = { NULL, NULL };
323 struct r_scope_elem **scope = symbol_scope;
325 bump_num_relocations ();
327 /* No other flag than DL_LOOKUP_ADD_DEPENDENCY or DL_LOOKUP_GSCOPE_LOCK
328 is allowed if we look up a versioned symbol. */
329 assert (version == NULL
330 || (flags & ~(DL_LOOKUP_ADD_DEPENDENCY | DL_LOOKUP_GSCOPE_LOCK))
331 == 0);
333 size_t i = 0;
334 if (__builtin_expect (skip_map != NULL, 0))
335 /* Search the relevant loaded objects for a definition. */
336 while ((*scope)->r_list[i] != skip_map)
337 ++i;
339 /* Search the relevant loaded objects for a definition. */
340 for (size_t start = i; *scope != NULL; start = 0, ++scope)
342 int res = do_lookup_x (undef_name, new_hash, &old_hash, *ref,
343 &current_value, *scope, start, version, flags,
344 skip_map, type_class);
345 if (res > 0)
346 break;
348 if (__builtin_expect (res, 0) < 0 && skip_map == NULL)
350 /* Oh, oh. The file named in the relocation entry does not
351 contain the needed symbol. This code is never reached
352 for unversioned lookups. */
353 assert (version != NULL);
354 const char *reference_name = undef_map ? undef_map->l_name : NULL;
356 /* XXX We cannot translate the message. */
357 _dl_signal_cerror (0, (reference_name[0]
358 ? reference_name
359 : (rtld_progname ?: "<main program>")),
360 N_("relocation error"),
361 make_string ("symbol ", undef_name, ", version ",
362 version->name,
363 " not defined in file ",
364 version->filename,
365 " with link time reference",
366 res == -2
367 ? " (no version symbols)" : ""));
368 *ref = NULL;
369 return 0;
373 if (__builtin_expect (current_value.s == NULL, 0))
375 if ((*ref == NULL || ELFW(ST_BIND) ((*ref)->st_info) != STB_WEAK)
376 && skip_map == NULL)
378 /* We could find no value for a strong reference. */
379 const char *reference_name = undef_map ? undef_map->l_name : "";
380 const char *versionstr = version ? ", version " : "";
381 const char *versionname = (version && version->name
382 ? version->name : "");
384 /* XXX We cannot translate the message. */
385 _dl_signal_cerror (0, (reference_name[0]
386 ? reference_name
387 : (rtld_progname ?: "<main program>")),
388 N_("symbol lookup error"),
389 make_string (undefined_msg, undef_name,
390 versionstr, versionname));
392 *ref = NULL;
393 return 0;
396 int protected = (*ref
397 && ELFW(ST_VISIBILITY) ((*ref)->st_other) == STV_PROTECTED);
398 if (__builtin_expect (protected != 0, 0))
400 /* It is very tricky. We need to figure out what value to
401 return for the protected symbol. */
402 if (type_class == ELF_RTYPE_CLASS_PLT)
404 if (current_value.s != NULL && current_value.m != undef_map)
406 current_value.s = *ref;
407 current_value.m = undef_map;
410 else
412 struct sym_val protected_value = { NULL, NULL };
414 for (scope = symbol_scope; *scope != NULL; i = 0, ++scope)
415 if (do_lookup_x (undef_name, new_hash, &old_hash, *ref,
416 &protected_value, *scope, i, version, flags,
417 skip_map, ELF_RTYPE_CLASS_PLT) != 0)
418 break;
420 if (protected_value.s != NULL && protected_value.m != undef_map)
422 current_value.s = *ref;
423 current_value.m = undef_map;
428 /* We have to check whether this would bind UNDEF_MAP to an object
429 in the global scope which was dynamically loaded. In this case
430 we have to prevent the latter from being unloaded unless the
431 UNDEF_MAP object is also unloaded. */
432 if (__builtin_expect (current_value.m->l_type == lt_loaded, 0)
433 /* Don't do this for explicit lookups as opposed to implicit
434 runtime lookups. */
435 && (flags & DL_LOOKUP_ADD_DEPENDENCY) != 0
436 /* Add UNDEF_MAP to the dependencies. */
437 && add_dependency (undef_map, current_value.m, flags) < 0)
438 /* Something went wrong. Perhaps the object we tried to reference
439 was just removed. Try finding another definition. */
440 return _dl_lookup_symbol_x (undef_name, undef_map, ref,
441 (flags & DL_LOOKUP_GSCOPE_LOCK)
442 ? undef_map->l_scope : symbol_scope,
443 version, type_class, flags, skip_map);
445 /* The object is used. */
446 current_value.m->l_used = 1;
448 if (__builtin_expect (GLRO(dl_debug_mask)
449 & (DL_DEBUG_BINDINGS|DL_DEBUG_PRELINK), 0))
450 _dl_debug_bindings (undef_name, undef_map, ref,
451 &current_value, version, type_class, protected);
453 *ref = current_value.s;
454 return LOOKUP_VALUE (current_value.m);
458 /* Cache the location of MAP's hash table. */
460 void
461 internal_function
462 _dl_setup_hash (struct link_map *map)
464 Elf_Symndx *hash;
465 Elf_Symndx nchain;
467 if (__builtin_expect (map->l_info[DT_ADDRTAGIDX (DT_GNU_HASH) + DT_NUM
468 + DT_THISPROCNUM + DT_VERSIONTAGNUM
469 + DT_EXTRANUM + DT_VALNUM] != NULL, 1))
471 Elf32_Word *hash32
472 = (void *) D_PTR (map, l_info[DT_ADDRTAGIDX (DT_GNU_HASH) + DT_NUM
473 + DT_THISPROCNUM + DT_VERSIONTAGNUM
474 + DT_EXTRANUM + DT_VALNUM]);
475 map->l_nbuckets = *hash32++;
476 Elf32_Word symbias = *hash32++;
477 Elf32_Word bitmask_nwords = *hash32++;
478 /* Must be a power of two. */
479 assert ((bitmask_nwords & (bitmask_nwords - 1)) == 0);
480 map->l_gnu_bitmask_idxbits = bitmask_nwords - 1;
481 map->l_gnu_shift = *hash32++;
483 map->l_gnu_bitmask = (ElfW(Addr) *) hash32;
484 hash32 += __ELF_NATIVE_CLASS / 32 * bitmask_nwords;
486 map->l_gnu_buckets = hash32;
487 hash32 += map->l_nbuckets;
488 map->l_gnu_chain_zero = hash32 - symbias;
489 return;
492 if (!map->l_info[DT_HASH])
493 return;
494 hash = (void *) D_PTR (map, l_info[DT_HASH]);
496 map->l_nbuckets = *hash++;
497 nchain = *hash++;
498 map->l_buckets = hash;
499 hash += map->l_nbuckets;
500 map->l_chain = hash;
504 static void
505 internal_function
506 _dl_debug_bindings (const char *undef_name, struct link_map *undef_map,
507 const ElfW(Sym) **ref, struct sym_val *value,
508 const struct r_found_version *version, int type_class,
509 int protected)
511 const char *reference_name = undef_map->l_name;
513 if (GLRO(dl_debug_mask) & DL_DEBUG_BINDINGS)
515 _dl_debug_printf ("binding file %s [%lu] to %s [%lu]: %s symbol `%s'",
516 (reference_name[0]
517 ? reference_name
518 : (rtld_progname ?: "<main program>")),
519 undef_map->l_ns,
520 value->m->l_name[0] ? value->m->l_name : rtld_progname,
521 value->m->l_ns,
522 protected ? "protected" : "normal", undef_name);
523 if (version)
524 _dl_debug_printf_c (" [%s]\n", version->name);
525 else
526 _dl_debug_printf_c ("\n");
528 #ifdef SHARED
529 if (GLRO(dl_debug_mask) & DL_DEBUG_PRELINK)
531 int conflict = 0;
532 struct sym_val val = { NULL, NULL };
534 if ((GLRO(dl_trace_prelink_map) == NULL
535 || GLRO(dl_trace_prelink_map) == GL(dl_ns)[LM_ID_BASE]._ns_loaded)
536 && undef_map != GL(dl_ns)[LM_ID_BASE]._ns_loaded)
538 const uint_fast32_t new_hash = dl_new_hash (undef_name);
539 unsigned long int old_hash = 0xffffffff;
541 do_lookup_x (undef_name, new_hash, &old_hash, *ref, &val,
542 undef_map->l_local_scope[0], 0, version, 0, NULL,
543 type_class);
545 if (val.s != value->s || val.m != value->m)
546 conflict = 1;
549 if (value->s
550 && (__builtin_expect (ELFW(ST_TYPE) (value->s->st_info)
551 == STT_TLS, 0)))
552 type_class = 4;
554 if (conflict
555 || GLRO(dl_trace_prelink_map) == undef_map
556 || GLRO(dl_trace_prelink_map) == NULL
557 || type_class == 4)
559 _dl_printf ("%s 0x%0*Zx 0x%0*Zx -> 0x%0*Zx 0x%0*Zx ",
560 conflict ? "conflict" : "lookup",
561 (int) sizeof (ElfW(Addr)) * 2,
562 (size_t) undef_map->l_map_start,
563 (int) sizeof (ElfW(Addr)) * 2,
564 (size_t) (((ElfW(Addr)) *ref) - undef_map->l_map_start),
565 (int) sizeof (ElfW(Addr)) * 2,
566 (size_t) (value->s ? value->m->l_map_start : 0),
567 (int) sizeof (ElfW(Addr)) * 2,
568 (size_t) (value->s ? value->s->st_value : 0));
570 if (conflict)
571 _dl_printf ("x 0x%0*Zx 0x%0*Zx ",
572 (int) sizeof (ElfW(Addr)) * 2,
573 (size_t) (val.s ? val.m->l_map_start : 0),
574 (int) sizeof (ElfW(Addr)) * 2,
575 (size_t) (val.s ? val.s->st_value : 0));
577 _dl_printf ("/%x %s\n", type_class, undef_name);
580 #endif