1 /* Look up a symbol in the loaded objects.
2 Copyright (C) 1995-2005, 2006, 2007 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
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.
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.
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
27 #include <dl-machine.h>
28 #include <sysdep-cancel.h>
29 #include <bits/libc-lock.h>
34 #define VERSTAG(tag) (DT_NUM + DT_THISPROCNUM + DT_VERSIONTAGIDX (tag))
36 /* We need this string more than once. */
37 static const char undefined_msg
[] = "undefined symbol: ";
47 #define make_string(string, rest...) \
49 const char *all[] = { string, ## rest }; \
54 for (cnt = 0; cnt < sizeof (all) / sizeof (all[0]); ++cnt) \
55 len += strlen (all[cnt]); \
57 cp = result = alloca (len); \
58 for (cnt = 0; cnt < sizeof (all) / sizeof (all[0]); ++cnt) \
59 cp = __stpcpy (cp, all[cnt]); \
64 /* Statistics function. */
66 # define bump_num_relocations() ++GL(dl_num_relocations)
68 # define bump_num_relocations() ((void) 0)
72 /* The actual lookup code. */
73 #include "do-lookup.h"
77 dl_new_hash (const char *s
)
79 uint_fast32_t h
= 5381;
80 for (unsigned char c
= *s
; c
!= '\0'; c
= *++s
)
82 return h
& 0xffffffff;
86 /* Add extra dependency on MAP to UNDEF_MAP. */
89 add_dependency (struct link_map
*undef_map
, struct link_map
*map
, int flags
)
91 struct link_map
*runp
;
95 /* Avoid self-references and references to objects which cannot be
100 /* Avoid references to objects which cannot be unloaded anyway. */
101 assert (map
->l_type
== lt_loaded
);
102 if ((map
->l_flags_1
& DF_1_NODELETE
) != 0)
105 struct link_map_reldeps
*l_reldeps
106 = atomic_forced_read (undef_map
->l_reldeps
);
108 /* Make sure l_reldeps is read before l_initfini. */
109 atomic_read_barrier ();
111 /* Determine whether UNDEF_MAP already has a reference to MAP. First
112 look in the normal dependencies. */
113 struct link_map
**l_initfini
= atomic_forced_read (undef_map
->l_initfini
);
114 if (l_initfini
!= NULL
)
116 for (i
= 0; l_initfini
[i
] != NULL
; ++i
)
117 if (l_initfini
[i
] == map
)
121 /* No normal dependency. See whether we already had to add it
122 to the special list of dynamic dependencies. */
123 unsigned int l_reldepsact
= 0;
124 if (l_reldeps
!= NULL
)
126 struct link_map
**list
= &l_reldeps
->list
[0];
127 l_reldepsact
= l_reldeps
->act
;
128 for (i
= 0; i
< l_reldepsact
; ++i
)
133 /* Save serial number of the target MAP. */
134 unsigned long long serial
= map
->l_serial
;
136 /* Make sure nobody can unload the object while we are at it. */
137 if (__builtin_expect (flags
& DL_LOOKUP_GSCOPE_LOCK
, 0))
139 /* We can't just call __rtld_lock_lock_recursive (GL(dl_load_lock))
140 here, that can result in ABBA deadlock. */
141 THREAD_GSCOPE_RESET_FLAG ();
142 __rtld_lock_lock_recursive (GL(dl_load_lock
));
143 /* While MAP value won't change, after THREAD_GSCOPE_RESET_FLAG ()
144 it can e.g. point to unallocated memory. So avoid the optimizer
145 treating the above read from MAP->l_serial as ensurance it
146 can safely dereference it. */
147 map
= atomic_forced_read (map
);
149 /* From this point on it is unsafe to dereference MAP, until it
150 has been found in one of the lists. */
152 /* Redo the l_initfini check in case undef_map's l_initfini
153 changed in the mean time. */
154 if (undef_map
->l_initfini
!= l_initfini
155 && undef_map
->l_initfini
!= NULL
)
157 l_initfini
= undef_map
->l_initfini
;
158 for (i
= 0; l_initfini
[i
] != NULL
; ++i
)
159 if (l_initfini
[i
] == map
)
163 /* Redo the l_reldeps check if undef_map's l_reldeps changed in
165 if (undef_map
->l_reldeps
!= NULL
)
167 if (undef_map
->l_reldeps
!= l_reldeps
)
169 struct link_map
**list
= &undef_map
->l_reldeps
->list
[0];
170 l_reldepsact
= undef_map
->l_reldeps
->act
;
171 for (i
= 0; i
< l_reldepsact
; ++i
)
175 else if (undef_map
->l_reldeps
->act
> l_reldepsact
)
177 struct link_map
**list
178 = &undef_map
->l_reldeps
->list
[0];
180 l_reldepsact
= undef_map
->l_reldeps
->act
;
181 for (; i
< l_reldepsact
; ++i
)
188 __rtld_lock_lock_recursive (GL(dl_load_lock
));
190 /* The object is not yet in the dependency list. Before we add
191 it make sure just one more time the object we are about to
192 reference is still available. There is a brief period in
193 which the object could have been removed since we found the
195 runp
= GL(dl_ns
)[undef_map
->l_ns
]._ns_loaded
;
196 while (runp
!= NULL
&& runp
!= map
)
201 /* The object is still available. */
203 /* MAP could have been dlclosed, freed and then some other dlopened
204 library could have the same link_map pointer. */
205 if (map
->l_serial
!= serial
)
208 /* Redo the NODELETE check, as when dl_load_lock wasn't held
209 yet this could have changed. */
210 if ((map
->l_flags_1
& DF_1_NODELETE
) != 0)
213 /* If the object with the undefined reference cannot be removed ever
214 just make sure the same is true for the object which contains the
216 if (undef_map
->l_type
!= lt_loaded
217 || (undef_map
->l_flags_1
& DF_1_NODELETE
) != 0)
219 map
->l_flags_1
|= DF_1_NODELETE
;
223 /* Add the reference now. */
224 if (__builtin_expect (l_reldepsact
>= undef_map
->l_reldepsmax
, 0))
226 /* Allocate more memory for the dependency list. Since this
227 can never happen during the startup phase we can use
229 struct link_map_reldeps
*newp
;
231 = undef_map
->l_reldepsmax
? undef_map
->l_reldepsmax
* 2 : 10;
233 newp
= malloc (sizeof (*newp
) + max
* sizeof (struct link_map
*));
236 /* If we didn't manage to allocate memory for the list this is
237 no fatal problem. We simply make sure the referenced object
238 cannot be unloaded. This is semantically the correct
240 map
->l_flags_1
|= DF_1_NODELETE
;
246 memcpy (&newp
->list
[0], &undef_map
->l_reldeps
->list
[0],
247 l_reldepsact
* sizeof (struct link_map
*));
248 newp
->list
[l_reldepsact
] = map
;
249 newp
->act
= l_reldepsact
+ 1;
250 atomic_write_barrier ();
251 void *old
= undef_map
->l_reldeps
;
252 undef_map
->l_reldeps
= newp
;
253 undef_map
->l_reldepsmax
= max
;
255 _dl_scope_free (old
);
260 undef_map
->l_reldeps
->list
[l_reldepsact
] = map
;
261 atomic_write_barrier ();
262 undef_map
->l_reldeps
->act
= l_reldepsact
+ 1;
265 /* Display information if we are debugging. */
266 if (__builtin_expect (GLRO(dl_debug_mask
) & DL_DEBUG_FILES
, 0))
268 \nfile=%s [%lu]; needed by %s [%lu] (relocation dependency)\n\n",
269 map
->l_name
[0] ? map
->l_name
: rtld_progname
,
272 ? undef_map
->l_name
: rtld_progname
,
276 /* Whoa, that was bad luck. We have to search again. */
280 /* Release the lock. */
281 __rtld_lock_unlock_recursive (GL(dl_load_lock
));
283 if (__builtin_expect (flags
& DL_LOOKUP_GSCOPE_LOCK
, 0))
284 THREAD_GSCOPE_SET_FLAG ();
289 if (map
->l_serial
!= serial
)
296 _dl_debug_bindings (const char *undef_name
, struct link_map
*undef_map
,
297 const ElfW(Sym
) **ref
, struct sym_val
*value
,
298 const struct r_found_version
*version
, int type_class
,
302 /* Search loaded objects' symbol tables for a definition of the symbol
303 UNDEF_NAME, perhaps with a requested version for the symbol.
305 We must never have calls to the audit functions inside this function
306 or in any function which gets called. If this would happen the audit
307 code might create a thread which can throw off all the scope locking. */
310 _dl_lookup_symbol_x (const char *undef_name
, struct link_map
*undef_map
,
311 const ElfW(Sym
) **ref
,
312 struct r_scope_elem
*symbol_scope
[],
313 const struct r_found_version
*version
,
314 int type_class
, int flags
, struct link_map
*skip_map
)
316 const uint_fast32_t new_hash
= dl_new_hash (undef_name
);
317 unsigned long int old_hash
= 0xffffffff;
318 struct sym_val current_value
= { NULL
, NULL
};
319 struct r_scope_elem
**scope
= symbol_scope
;
321 bump_num_relocations ();
323 /* No other flag than DL_LOOKUP_ADD_DEPENDENCY or DL_LOOKUP_GSCOPE_LOCK
324 is allowed if we look up a versioned symbol. */
325 assert (version
== NULL
326 || (flags
& ~(DL_LOOKUP_ADD_DEPENDENCY
| DL_LOOKUP_GSCOPE_LOCK
))
330 if (__builtin_expect (skip_map
!= NULL
, 0))
331 /* Search the relevant loaded objects for a definition. */
332 while ((*scope
)->r_list
[i
] != skip_map
)
335 /* Search the relevant loaded objects for a definition. */
336 for (size_t start
= i
; *scope
!= NULL
; start
= 0, ++scope
)
338 int res
= do_lookup_x (undef_name
, new_hash
, &old_hash
, *ref
,
339 ¤t_value
, *scope
, start
, version
, flags
,
340 skip_map
, type_class
);
344 if (__builtin_expect (res
, 0) < 0 && skip_map
== NULL
)
346 /* Oh, oh. The file named in the relocation entry does not
347 contain the needed symbol. This code is never reached
348 for unversioned lookups. */
349 assert (version
!= NULL
);
350 const char *reference_name
= undef_map
? undef_map
->l_name
: NULL
;
352 /* XXX We cannot translate the message. */
353 _dl_signal_cerror (0, (reference_name
[0]
355 : (rtld_progname
?: "<main program>")),
356 N_("relocation error"),
357 make_string ("symbol ", undef_name
, ", version ",
359 " not defined in file ",
361 " with link time reference",
363 ? " (no version symbols)" : ""));
369 if (__builtin_expect (current_value
.s
== NULL
, 0))
371 if ((*ref
== NULL
|| ELFW(ST_BIND
) ((*ref
)->st_info
) != STB_WEAK
)
374 /* We could find no value for a strong reference. */
375 const char *reference_name
= undef_map
? undef_map
->l_name
: "";
376 const char *versionstr
= version
? ", version " : "";
377 const char *versionname
= (version
&& version
->name
378 ? version
->name
: "");
380 /* XXX We cannot translate the message. */
381 _dl_signal_cerror (0, (reference_name
[0]
383 : (rtld_progname
?: "<main program>")),
384 N_("symbol lookup error"),
385 make_string (undefined_msg
, undef_name
,
386 versionstr
, versionname
));
392 int protected = (*ref
393 && ELFW(ST_VISIBILITY
) ((*ref
)->st_other
) == STV_PROTECTED
);
394 if (__builtin_expect (protected != 0, 0))
396 /* It is very tricky. We need to figure out what value to
397 return for the protected symbol. */
398 if (type_class
== ELF_RTYPE_CLASS_PLT
)
400 if (current_value
.s
!= NULL
&& current_value
.m
!= undef_map
)
402 current_value
.s
= *ref
;
403 current_value
.m
= undef_map
;
408 struct sym_val protected_value
= { NULL
, NULL
};
410 for (scope
= symbol_scope
; *scope
!= NULL
; i
= 0, ++scope
)
411 if (do_lookup_x (undef_name
, new_hash
, &old_hash
, *ref
,
412 &protected_value
, *scope
, i
, version
, flags
,
413 skip_map
, ELF_RTYPE_CLASS_PLT
) != 0)
416 if (protected_value
.s
!= NULL
&& protected_value
.m
!= undef_map
)
418 current_value
.s
= *ref
;
419 current_value
.m
= undef_map
;
424 /* We have to check whether this would bind UNDEF_MAP to an object
425 in the global scope which was dynamically loaded. In this case
426 we have to prevent the latter from being unloaded unless the
427 UNDEF_MAP object is also unloaded. */
428 if (__builtin_expect (current_value
.m
->l_type
== lt_loaded
, 0)
429 /* Don't do this for explicit lookups as opposed to implicit
431 && (flags
& DL_LOOKUP_ADD_DEPENDENCY
) != 0
432 /* Add UNDEF_MAP to the dependencies. */
433 && add_dependency (undef_map
, current_value
.m
, flags
) < 0)
434 /* Something went wrong. Perhaps the object we tried to reference
435 was just removed. Try finding another definition. */
436 return _dl_lookup_symbol_x (undef_name
, undef_map
, ref
,
437 (flags
& DL_LOOKUP_GSCOPE_LOCK
)
438 ? undef_map
->l_scope
: symbol_scope
,
439 version
, type_class
, flags
, skip_map
);
441 /* The object is used. */
442 current_value
.m
->l_used
= 1;
444 if (__builtin_expect (GLRO(dl_debug_mask
)
445 & (DL_DEBUG_BINDINGS
|DL_DEBUG_PRELINK
), 0))
446 _dl_debug_bindings (undef_name
, undef_map
, ref
,
447 ¤t_value
, version
, type_class
, protected);
449 *ref
= current_value
.s
;
450 return LOOKUP_VALUE (current_value
.m
);
454 /* Cache the location of MAP's hash table. */
458 _dl_setup_hash (struct link_map
*map
)
463 if (__builtin_expect (map
->l_info
[DT_ADDRTAGIDX (DT_GNU_HASH
) + DT_NUM
464 + DT_THISPROCNUM
+ DT_VERSIONTAGNUM
465 + DT_EXTRANUM
+ DT_VALNUM
] != NULL
, 1))
468 = (void *) D_PTR (map
, l_info
[DT_ADDRTAGIDX (DT_GNU_HASH
) + DT_NUM
469 + DT_THISPROCNUM
+ DT_VERSIONTAGNUM
470 + DT_EXTRANUM
+ DT_VALNUM
]);
471 map
->l_nbuckets
= *hash32
++;
472 Elf32_Word symbias
= *hash32
++;
473 Elf32_Word bitmask_nwords
= *hash32
++;
474 /* Must be a power of two. */
475 assert ((bitmask_nwords
& (bitmask_nwords
- 1)) == 0);
476 map
->l_gnu_bitmask_idxbits
= bitmask_nwords
- 1;
477 map
->l_gnu_shift
= *hash32
++;
479 map
->l_gnu_bitmask
= (ElfW(Addr
) *) hash32
;
480 hash32
+= __ELF_NATIVE_CLASS
/ 32 * bitmask_nwords
;
482 map
->l_gnu_buckets
= hash32
;
483 hash32
+= map
->l_nbuckets
;
484 map
->l_gnu_chain_zero
= hash32
- symbias
;
488 if (!map
->l_info
[DT_HASH
])
490 hash
= (void *) D_PTR (map
, l_info
[DT_HASH
]);
492 map
->l_nbuckets
= *hash
++;
494 map
->l_buckets
= hash
;
495 hash
+= map
->l_nbuckets
;
502 _dl_debug_bindings (const char *undef_name
, struct link_map
*undef_map
,
503 const ElfW(Sym
) **ref
, struct sym_val
*value
,
504 const struct r_found_version
*version
, int type_class
,
507 const char *reference_name
= undef_map
->l_name
;
509 if (GLRO(dl_debug_mask
) & DL_DEBUG_BINDINGS
)
511 _dl_debug_printf ("binding file %s [%lu] to %s [%lu]: %s symbol `%s'",
514 : (rtld_progname
?: "<main program>")),
516 value
->m
->l_name
[0] ? value
->m
->l_name
: rtld_progname
,
518 protected ? "protected" : "normal", undef_name
);
520 _dl_debug_printf_c (" [%s]\n", version
->name
);
522 _dl_debug_printf_c ("\n");
525 if (GLRO(dl_debug_mask
) & DL_DEBUG_PRELINK
)
528 struct sym_val val
= { NULL
, NULL
};
530 if ((GLRO(dl_trace_prelink_map
) == NULL
531 || GLRO(dl_trace_prelink_map
) == GL(dl_ns
)[LM_ID_BASE
]._ns_loaded
)
532 && undef_map
!= GL(dl_ns
)[LM_ID_BASE
]._ns_loaded
)
534 const uint_fast32_t new_hash
= dl_new_hash (undef_name
);
535 unsigned long int old_hash
= 0xffffffff;
537 do_lookup_x (undef_name
, new_hash
, &old_hash
, *ref
, &val
,
538 undef_map
->l_local_scope
[0], 0, version
, 0, NULL
,
541 if (val
.s
!= value
->s
|| val
.m
!= value
->m
)
546 && (__builtin_expect (ELFW(ST_TYPE
) (value
->s
->st_info
)
551 || GLRO(dl_trace_prelink_map
) == undef_map
552 || GLRO(dl_trace_prelink_map
) == NULL
555 _dl_printf ("%s 0x%0*Zx 0x%0*Zx -> 0x%0*Zx 0x%0*Zx ",
556 conflict
? "conflict" : "lookup",
557 (int) sizeof (ElfW(Addr
)) * 2,
558 (size_t) undef_map
->l_map_start
,
559 (int) sizeof (ElfW(Addr
)) * 2,
560 (size_t) (((ElfW(Addr
)) *ref
) - undef_map
->l_map_start
),
561 (int) sizeof (ElfW(Addr
)) * 2,
562 (size_t) (value
->s
? value
->m
->l_map_start
: 0),
563 (int) sizeof (ElfW(Addr
)) * 2,
564 (size_t) (value
->s
? value
->s
->st_value
: 0));
567 _dl_printf ("x 0x%0*Zx 0x%0*Zx ",
568 (int) sizeof (ElfW(Addr
)) * 2,
569 (size_t) (val
.s
? val
.m
->l_map_start
: 0),
570 (int) sizeof (ElfW(Addr
)) * 2,
571 (size_t) (val
.s
? val
.s
->st_value
: 0));
573 _dl_printf ("/%x %s\n", type_class
, undef_name
);