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
31 #include <dl-machine.h>
32 #include <sysdep-cancel.h>
33 #include <bits/libc-lock.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: ";
51 #define make_string(string, rest...) \
53 const char *all[] = { string, ## rest }; \
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]); \
68 /* Statistics function. */
70 # define bump_num_relocations() ++GL(dl_num_relocations)
72 # define bump_num_relocations() ((void) 0)
76 /* The actual lookup code. */
77 #include "do-lookup.h"
81 dl_new_hash (const char *s
)
83 uint_fast32_t h
= 5381;
84 for (unsigned char c
= *s
; c
!= '\0'; c
= *++s
)
86 return h
& 0xffffffff;
90 /* Add extra dependency on MAP to UNDEF_MAP. */
93 add_dependency (struct link_map
*undef_map
, struct link_map
*map
, int flags
)
95 struct link_map
*runp
;
99 /* Avoid self-references and references to objects which cannot be
101 if (undef_map
== map
)
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)
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
)
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
)
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
)
167 /* Redo the l_reldeps check if undef_map's l_reldeps changed in
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
)
179 else if (undef_map
->l_reldeps
->act
> l_reldepsact
)
181 struct link_map
**list
182 = &undef_map
->l_reldeps
->list
[0];
184 l_reldepsact
= undef_map
->l_reldeps
->act
;
185 for (; i
< l_reldepsact
; ++i
)
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
199 runp
= GL(dl_ns
)[undef_map
->l_ns
]._ns_loaded
;
200 while (runp
!= NULL
&& runp
!= map
)
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
)
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)
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
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
;
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
233 struct link_map_reldeps
*newp
;
235 = undef_map
->l_reldepsmax
? undef_map
->l_reldepsmax
* 2 : 10;
237 newp
= malloc (sizeof (*newp
) + max
* sizeof (struct link_map
*));
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
244 map
->l_flags_1
|= DF_1_NODELETE
;
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
;
259 _dl_scope_free (old
);
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))
272 \nfile=%s [%lu]; needed by %s [%lu] (relocation dependency)\n\n",
273 map
->l_name
[0] ? map
->l_name
: rtld_progname
,
276 ? undef_map
->l_name
: rtld_progname
,
280 /* Whoa, that was bad luck. We have to search again. */
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 ();
293 if (map
->l_serial
!= serial
)
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
,
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. */
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
))
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
)
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 ¤t_value
, *scope
, start
, version
, flags
,
344 skip_map
, type_class
);
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]
359 : (rtld_progname
?: "<main program>")),
360 N_("relocation error"),
361 make_string ("symbol ", undef_name
, ", version ",
363 " not defined in file ",
365 " with link time reference",
367 ? " (no version symbols)" : ""));
373 if (__builtin_expect (current_value
.s
== NULL
, 0))
375 if ((*ref
== NULL
|| ELFW(ST_BIND
) ((*ref
)->st_info
) != STB_WEAK
)
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]
387 : (rtld_progname
?: "<main program>")),
388 N_("symbol lookup error"),
389 make_string (undefined_msg
, undef_name
,
390 versionstr
, versionname
));
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
;
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)
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
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 ¤t_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. */
462 _dl_setup_hash (struct link_map
*map
)
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))
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
;
492 if (!map
->l_info
[DT_HASH
])
494 hash
= (void *) D_PTR (map
, l_info
[DT_HASH
]);
496 map
->l_nbuckets
= *hash
++;
498 map
->l_buckets
= hash
;
499 hash
+= map
->l_nbuckets
;
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
,
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'",
518 : (rtld_progname
?: "<main program>")),
520 value
->m
->l_name
[0] ? value
->m
->l_name
: rtld_progname
,
522 protected ? "protected" : "normal", undef_name
);
524 _dl_debug_printf_c (" [%s]\n", version
->name
);
526 _dl_debug_printf_c ("\n");
529 if (GLRO(dl_debug_mask
) & DL_DEBUG_PRELINK
)
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
,
545 if (val
.s
!= value
->s
|| val
.m
!= value
->m
)
550 && (__builtin_expect (ELFW(ST_TYPE
) (value
->s
->st_info
)
555 || GLRO(dl_trace_prelink_map
) == undef_map
556 || GLRO(dl_trace_prelink_map
) == NULL
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));
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
);