* sysdeps/mach/hurd/tmpfile.c: Remove USE_IN_LIBIO conditionals.
[glibc.git] / elf / dl-lookup.c
blob2b7473662fdba90238aec9032bcb5a02d7ef275a
1 /* Look up a symbol in the loaded objects.
2 Copyright (C) 1995-2002, 2003 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
18 02111-1307 USA. */
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>
31 #include <assert.h>
33 #define VERSTAG(tag) (DT_NUM + DT_THISPROCNUM + DT_VERSIONTAGIDX (tag))
35 /* We need this string more than once. */
36 static const char undefined_msg[] = "undefined symbol: ";
39 struct sym_val
41 const ElfW(Sym) *s;
42 struct link_map *m;
46 #define make_string(string, rest...) \
47 ({ \
48 const char *all[] = { string, ## rest }; \
49 size_t len, cnt; \
50 char *result, *cp; \
52 len = 1; \
53 for (cnt = 0; cnt < sizeof (all) / sizeof (all[0]); ++cnt) \
54 len += strlen (all[cnt]); \
56 cp = result = alloca (len); \
57 for (cnt = 0; cnt < sizeof (all) / sizeof (all[0]); ++cnt) \
58 cp = __stpcpy (cp, all[cnt]); \
60 result; \
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
72 /* We have two different situations when looking up a simple: with or
73 without versioning. gcc is not able to optimize a single function
74 definition serving for both purposes so we define two functions. */
75 #define VERSIONED 0
76 #include "do-lookup.h"
78 #define VERSIONED 1
79 #include "do-lookup.h"
82 /* Add extra dependency on MAP to UNDEF_MAP. */
83 static int
84 internal_function
85 add_dependency (struct link_map *undef_map, struct link_map *map)
87 struct link_map **list;
88 struct link_map *runp;
89 unsigned int act;
90 unsigned int i;
91 int result = 0;
93 /* Avoid self-references and references to objects which cannot be
94 unloaded anyway. */
95 if (undef_map == map)
96 return 0;
98 /* Make sure nobody can unload the object while we are at it. */
99 __rtld_lock_lock_recursive (GL(dl_load_lock));
101 /* Don't create cross-reference between modules which are
102 dynamically loaded by the same dlopen() call. */
103 if (undef_map->l_opencount == 0 && map->l_opencount == 0)
104 goto out;
106 /* Avoid references to objects which cannot be unloaded anyway. */
107 if (map->l_type != lt_loaded
108 || (map->l_flags_1 & DF_1_NODELETE) != 0)
109 goto out;
111 /* If the object with the undefined reference cannot be removed ever
112 just make sure the same is true for the object which contains the
113 definition. */
114 if (undef_map->l_type != lt_loaded
115 || (undef_map->l_flags_1 & DF_1_NODELETE) != 0)
117 ++map->l_opencount;
118 map->l_flags |= DF_1_NODELETE;
119 goto out;
122 /* Determine whether UNDEF_MAP already has a reference to MAP. First
123 look in the normal dependencies. */
124 if (undef_map->l_searchlist.r_list != NULL)
126 list = undef_map->l_initfini;
128 for (i = 0; list[i] != NULL; ++i)
129 if (list[i] == map)
130 goto out;
133 /* No normal dependency. See whether we already had to add it
134 to the special list of dynamic dependencies. */
135 list = undef_map->l_reldeps;
136 act = undef_map->l_reldepsact;
138 for (i = 0; i < act; ++i)
139 if (list[i] == map)
140 goto out;
142 /* The object is not yet in the dependency list. Before we add
143 it make sure just one more time the object we are about to
144 reference is still available. There is a brief period in
145 which the object could have been removed since we found the
146 definition. */
147 runp = GL(dl_loaded);
148 while (runp != NULL && runp != map)
149 runp = runp->l_next;
151 if (runp != NULL)
153 /* The object is still available. Add the reference now. */
154 if (__builtin_expect (act >= undef_map->l_reldepsmax, 0))
156 /* Allocate more memory for the dependency list. Since this
157 can never happen during the startup phase we can use
158 `realloc'. */
159 void *newp;
161 undef_map->l_reldepsmax += 5;
162 newp = realloc (undef_map->l_reldeps,
163 undef_map->l_reldepsmax
164 * sizeof (struct link_map *));
166 if (__builtin_expect (newp != NULL, 1))
167 undef_map->l_reldeps = (struct link_map **) newp;
168 else
169 /* Correct the addition. */
170 undef_map->l_reldepsmax -= 5;
173 /* If we didn't manage to allocate memory for the list this is
174 no fatal mistake. We simply increment the use counter of the
175 referenced object and don't record the dependencies. This
176 means this increment can never be reverted and the object
177 will never be unloaded. This is semantically the correct
178 behavior. */
179 if (__builtin_expect (act < undef_map->l_reldepsmax, 1))
180 undef_map->l_reldeps[undef_map->l_reldepsact++] = map;
182 if (map->l_searchlist.r_list != NULL)
183 /* And increment the counter in the referenced object. */
184 ++map->l_opencount;
185 else
186 /* We have to bump the counts for all dependencies since so far
187 this object was only a normal or transitive dependency.
188 Now it might be closed with _dl_close() directly. */
189 for (list = map->l_initfini; *list != NULL; ++list)
190 ++(*list)->l_opencount;
192 /* Display information if we are debugging. */
193 if (__builtin_expect (GL(dl_debug_mask) & DL_DEBUG_FILES, 0))
194 INTUSE(_dl_debug_printf) ("\
195 \nfile=%s; needed by %s (relocation dependency)\n\n",
196 map->l_name[0] ? map->l_name : rtld_progname,
197 undef_map->l_name[0]
198 ? undef_map->l_name : rtld_progname);
200 else
201 /* Whoa, that was bad luck. We have to search again. */
202 result = -1;
204 out:
205 /* Release the lock. */
206 __rtld_lock_unlock_recursive (GL(dl_load_lock));
208 return result;
211 static int
212 internal_function
213 _dl_do_lookup (const char *undef_name, unsigned long int hash,
214 const ElfW(Sym) *ref, struct sym_val *result,
215 struct r_scope_elem *scope, size_t i, int flags,
216 struct link_map *skip, int type_class);
217 static int
218 internal_function
219 _dl_do_lookup_versioned (const char *undef_name, unsigned long int hash,
220 const ElfW(Sym) *ref, struct sym_val *result,
221 struct r_scope_elem *scope, size_t i,
222 const struct r_found_version *const version,
223 struct link_map *skip, int type_class);
225 static void
226 internal_function
227 _dl_debug_bindings (const char *undef_name, struct link_map *undef_map,
228 const ElfW(Sym) **ref, struct r_scope_elem *symbol_scope[],
229 struct sym_val *value,
230 const struct r_found_version *version, int type_class,
231 int protected);
233 /* Search loaded objects' symbol tables for a definition of the symbol
234 UNDEF_NAME. */
236 lookup_t
237 internal_function
238 _dl_lookup_symbol (const char *undef_name, struct link_map *undef_map,
239 const ElfW(Sym) **ref, struct r_scope_elem *symbol_scope[],
240 int type_class, int flags)
242 const unsigned long int hash = _dl_elf_hash (undef_name);
243 struct sym_val current_value = { NULL, NULL };
244 struct r_scope_elem **scope;
245 int protected;
247 bump_num_relocations ();
249 /* Search the relevant loaded objects for a definition. */
250 for (scope = symbol_scope; *scope; ++scope)
251 if (do_lookup (undef_name, hash, *ref, &current_value, *scope, 0, flags,
252 NULL, type_class))
253 break;
255 if (__builtin_expect (current_value.s == NULL, 0))
257 const char *reference_name = undef_map ? undef_map->l_name : NULL;
259 if (*ref == NULL || ELFW(ST_BIND) ((*ref)->st_info) != STB_WEAK)
260 /* We could find no value for a strong reference. */
261 /* XXX We cannot translate the messages. */
262 _dl_signal_cerror (0, (reference_name[0]
263 ? reference_name
264 : (rtld_progname ?: "<main program>")),
265 N_("relocation error"),
266 make_string (undefined_msg, undef_name));
267 *ref = NULL;
268 return 0;
271 protected = *ref && ELFW(ST_VISIBILITY) ((*ref)->st_other) == STV_PROTECTED;
272 if (__builtin_expect (protected != 0, 0))
274 /* It is very tricky. We need to figure out what value to
275 return for the protected symbol. */
276 if (type_class == ELF_RTYPE_CLASS_PLT)
278 if (current_value.s != NULL && current_value.m != undef_map)
280 current_value.s = *ref;
281 current_value.m = undef_map;
284 else
286 struct sym_val protected_value = { NULL, NULL };
288 for (scope = symbol_scope; *scope; ++scope)
289 if (_dl_do_lookup (undef_name, hash, *ref,
290 &protected_value, *scope, 0, flags,
291 NULL, ELF_RTYPE_CLASS_PLT))
292 break;
294 if (protected_value.s != NULL
295 && protected_value.m != undef_map)
297 current_value.s = *ref;
298 current_value.m = undef_map;
303 /* We have to check whether this would bind UNDEF_MAP to an object
304 in the global scope which was dynamically loaded. In this case
305 we have to prevent the latter from being unloaded unless the
306 UNDEF_MAP object is also unloaded. */
307 if (__builtin_expect (current_value.m->l_type == lt_loaded, 0)
308 /* Don't do this for explicit lookups as opposed to implicit
309 runtime lookups. */
310 && (flags & DL_LOOKUP_ADD_DEPENDENCY) != 0
311 /* Add UNDEF_MAP to the dependencies. */
312 && add_dependency (undef_map, current_value.m) < 0)
313 /* Something went wrong. Perhaps the object we tried to reference
314 was just removed. Try finding another definition. */
315 return INTUSE(_dl_lookup_symbol) (undef_name, undef_map, ref,
316 symbol_scope, type_class, flags);
318 if (__builtin_expect (GL(dl_debug_mask)
319 & (DL_DEBUG_BINDINGS|DL_DEBUG_PRELINK), 0))
320 _dl_debug_bindings (undef_name, undef_map, ref, symbol_scope,
321 &current_value, NULL, type_class, protected);
323 *ref = current_value.s;
324 return LOOKUP_VALUE (current_value.m);
326 INTDEF (_dl_lookup_symbol)
329 /* This function is nearly the same as `_dl_lookup_symbol' but it
330 skips in the first list all objects until SKIP_MAP is found. I.e.,
331 it only considers objects which were loaded after the described
332 object. If there are more search lists the object described by
333 SKIP_MAP is only skipped. */
334 lookup_t
335 internal_function
336 _dl_lookup_symbol_skip (const char *undef_name,
337 struct link_map *undef_map, const ElfW(Sym) **ref,
338 struct r_scope_elem *symbol_scope[],
339 struct link_map *skip_map)
341 const unsigned long int hash = _dl_elf_hash (undef_name);
342 struct sym_val current_value = { NULL, NULL };
343 struct r_scope_elem **scope;
344 size_t i;
345 int protected;
347 bump_num_relocations ();
349 /* Search the relevant loaded objects for a definition. */
350 scope = symbol_scope;
351 for (i = 0; (*scope)->r_list[i] != skip_map; ++i)
352 assert (i < (*scope)->r_nlist);
354 if (! _dl_do_lookup (undef_name, hash, *ref, &current_value, *scope, i,
355 DL_LOOKUP_RETURN_NEWEST, skip_map, 0))
356 while (*++scope)
357 if (_dl_do_lookup (undef_name, hash, *ref, &current_value, *scope, 0,
358 DL_LOOKUP_RETURN_NEWEST, skip_map, 0))
359 break;
361 if (__builtin_expect (current_value.s == NULL, 0))
363 *ref = NULL;
364 return 0;
367 protected = *ref && ELFW(ST_VISIBILITY) ((*ref)->st_other) == STV_PROTECTED;
369 if (__builtin_expect (protected != 0, 0))
371 /* It is very tricky. We need to figure out what value to
372 return for the protected symbol. */
373 struct sym_val protected_value = { NULL, NULL };
375 if (i >= (*scope)->r_nlist
376 || !_dl_do_lookup (undef_name, hash, *ref, &protected_value, *scope,
377 i, DL_LOOKUP_RETURN_NEWEST, skip_map,
378 ELF_RTYPE_CLASS_PLT))
379 while (*++scope)
380 if (_dl_do_lookup (undef_name, hash, *ref, &protected_value, *scope,
381 0, DL_LOOKUP_RETURN_NEWEST, skip_map,
382 ELF_RTYPE_CLASS_PLT))
383 break;
385 if (protected_value.s != NULL && protected_value.m != undef_map)
387 current_value.s = *ref;
388 current_value.m = undef_map;
392 if (__builtin_expect (GL(dl_debug_mask)
393 & (DL_DEBUG_BINDINGS|DL_DEBUG_PRELINK), 0))
394 _dl_debug_bindings (undef_name, undef_map, ref, symbol_scope,
395 &current_value, NULL, 0, protected);
397 *ref = current_value.s;
398 return LOOKUP_VALUE (current_value.m);
402 /* This function works like _dl_lookup_symbol but it takes an
403 additional arguement with the version number of the requested
404 symbol.
406 XXX We'll see whether we need this separate function. */
407 lookup_t
408 internal_function
409 _dl_lookup_versioned_symbol (const char *undef_name,
410 struct link_map *undef_map, const ElfW(Sym) **ref,
411 struct r_scope_elem *symbol_scope[],
412 const struct r_found_version *version,
413 int type_class, int flags)
415 const unsigned long int hash = _dl_elf_hash (undef_name);
416 struct sym_val current_value = { NULL, NULL };
417 struct r_scope_elem **scope;
418 int protected;
420 bump_num_relocations ();
422 /* No other flag than DL_LOOKUP_ADD_DEPENDENCY is allowed. */
423 assert (flags == 0 || flags == DL_LOOKUP_ADD_DEPENDENCY);
425 /* Search the relevant loaded objects for a definition. */
426 for (scope = symbol_scope; *scope; ++scope)
428 int res = do_lookup_versioned (undef_name, hash, *ref, &current_value,
429 *scope, 0, version, NULL, type_class);
430 if (res > 0)
431 break;
433 if (__builtin_expect (res, 0) < 0)
435 /* Oh, oh. The file named in the relocation entry does not
436 contain the needed symbol. */
437 const char *reference_name = undef_map ? undef_map->l_name : NULL;
439 /* XXX We cannot translate the message. */
440 _dl_signal_cerror (0, (reference_name[0]
441 ? reference_name
442 : (rtld_progname ?: "<main program>")),
443 N_("relocation error"),
444 make_string ("symbol ", undef_name, ", version ",
445 version->name,
446 " not defined in file ",
447 version->filename,
448 " with link time reference",
449 res == -2
450 ? " (no version symbols)" : ""));
451 *ref = NULL;
452 return 0;
456 if (__builtin_expect (current_value.s == NULL, 0))
458 if (*ref == NULL || ELFW(ST_BIND) ((*ref)->st_info) != STB_WEAK)
460 /* We could find no value for a strong reference. */
461 const char *reference_name = undef_map ? undef_map->l_name : NULL;
463 /* XXX We cannot translate the message. */
464 _dl_signal_cerror (0, (reference_name[0]
465 ? reference_name
466 : (rtld_progname ?: "<main program>")), NULL,
467 make_string (undefined_msg, undef_name,
468 ", version ",
469 version->name ?: NULL));
471 *ref = NULL;
472 return 0;
475 protected = *ref && ELFW(ST_VISIBILITY) ((*ref)->st_other) == STV_PROTECTED;
477 if (__builtin_expect (protected != 0, 0))
479 /* It is very tricky. We need to figure out what value to
480 return for the protected symbol. */
481 if (type_class == ELF_RTYPE_CLASS_PLT)
483 if (current_value.s != NULL && current_value.m != undef_map)
485 current_value.s = *ref;
486 current_value.m = undef_map;
489 else
491 struct sym_val protected_value = { NULL, NULL };
493 for (scope = symbol_scope; *scope; ++scope)
494 if (_dl_do_lookup_versioned (undef_name, hash, *ref,
495 &protected_value,
496 *scope, 0, version, NULL,
497 ELF_RTYPE_CLASS_PLT))
498 break;
500 if (protected_value.s != NULL
501 && protected_value.m != undef_map)
503 current_value.s = *ref;
504 current_value.m = undef_map;
509 /* We have to check whether this would bind UNDEF_MAP to an object
510 in the global scope which was dynamically loaded. In this case
511 we have to prevent the latter from being unloaded unless the
512 UNDEF_MAP object is also unloaded. */
513 if (__builtin_expect (current_value.m->l_type == lt_loaded, 0)
514 /* Don't do this for explicit lookups as opposed to implicit
515 runtime lookups. */
516 && flags != 0
517 /* Add UNDEF_MAP to the dependencies. */
518 && add_dependency (undef_map, current_value.m) < 0)
519 /* Something went wrong. Perhaps the object we tried to reference
520 was just removed. Try finding another definition. */
521 return INTUSE(_dl_lookup_versioned_symbol) (undef_name, undef_map,
522 ref, symbol_scope,
523 version, type_class, flags);
525 if (__builtin_expect (GL(dl_debug_mask)
526 & (DL_DEBUG_BINDINGS|DL_DEBUG_PRELINK), 0))
527 _dl_debug_bindings (undef_name, undef_map, ref, symbol_scope,
528 &current_value, version, type_class, protected);
530 *ref = current_value.s;
531 return LOOKUP_VALUE (current_value.m);
533 INTDEF (_dl_lookup_versioned_symbol)
536 /* Similar to _dl_lookup_symbol_skip but takes an additional argument
537 with the version we are looking for. */
538 lookup_t
539 internal_function
540 _dl_lookup_versioned_symbol_skip (const char *undef_name,
541 struct link_map *undef_map,
542 const ElfW(Sym) **ref,
543 struct r_scope_elem *symbol_scope[],
544 const struct r_found_version *version,
545 struct link_map *skip_map)
547 const char *reference_name = undef_map->l_name;
548 const unsigned long int hash = _dl_elf_hash (undef_name);
549 struct sym_val current_value = { NULL, NULL };
550 struct r_scope_elem **scope;
551 size_t i;
552 int protected;
554 bump_num_relocations ();
556 /* Search the relevant loaded objects for a definition. */
557 scope = symbol_scope;
558 for (i = 0; (*scope)->r_list[i] != skip_map; ++i)
559 assert (i < (*scope)->r_nlist);
561 if (! _dl_do_lookup_versioned (undef_name, hash, *ref, &current_value,
562 *scope, i, version, skip_map, 0))
563 while (*++scope)
564 if (_dl_do_lookup_versioned (undef_name, hash, *ref, &current_value,
565 *scope, 0, version, skip_map, 0))
566 break;
568 if (__builtin_expect (current_value.s == NULL, 0))
570 if (*ref == NULL || ELFW(ST_BIND) ((*ref)->st_info) != STB_WEAK)
572 /* We could find no value for a strong reference. */
573 const size_t len = strlen (undef_name);
574 char buf[sizeof undefined_msg + len];
575 __mempcpy (__mempcpy (buf, undefined_msg, sizeof undefined_msg - 1),
576 undef_name, len + 1);
577 /* XXX We cannot translate the messages. */
578 _dl_signal_cerror (0, (reference_name[0]
579 ? reference_name
580 : (rtld_progname ?: "<main program>")),
581 NULL, buf);
583 *ref = NULL;
584 return 0;
587 protected = *ref && ELFW(ST_VISIBILITY) ((*ref)->st_other) == STV_PROTECTED;
589 if (__builtin_expect (protected != 0, 0))
591 /* It is very tricky. We need to figure out what value to
592 return for the protected symbol. */
593 struct sym_val protected_value = { NULL, NULL };
595 if (i >= (*scope)->r_nlist
596 || !_dl_do_lookup_versioned (undef_name, hash, *ref,
597 &protected_value, *scope, i, version,
598 skip_map, ELF_RTYPE_CLASS_PLT))
599 while (*++scope)
600 if (_dl_do_lookup_versioned (undef_name, hash, *ref,
601 &protected_value, *scope, 0, version,
602 skip_map, ELF_RTYPE_CLASS_PLT))
603 break;
605 if (protected_value.s != NULL && protected_value.m != undef_map)
607 current_value.s = *ref;
608 current_value.m = undef_map;
612 if (__builtin_expect (GL(dl_debug_mask)
613 & (DL_DEBUG_BINDINGS|DL_DEBUG_PRELINK), 0))
614 _dl_debug_bindings (undef_name, undef_map, ref, symbol_scope,
615 &current_value, version, 0, protected);
617 *ref = current_value.s;
618 return LOOKUP_VALUE (current_value.m);
622 /* Cache the location of MAP's hash table. */
624 void
625 internal_function
626 _dl_setup_hash (struct link_map *map)
628 Elf_Symndx *hash;
629 Elf_Symndx nchain;
631 if (!map->l_info[DT_HASH])
632 return;
633 hash = (void *) D_PTR (map, l_info[DT_HASH]);
635 map->l_nbuckets = *hash++;
636 nchain = *hash++;
637 map->l_buckets = hash;
638 hash += map->l_nbuckets;
639 map->l_chain = hash;
643 static void
644 internal_function
645 _dl_debug_bindings (const char *undef_name, struct link_map *undef_map,
646 const ElfW(Sym) **ref, struct r_scope_elem *symbol_scope[],
647 struct sym_val *value,
648 const struct r_found_version *version, int type_class,
649 int protected)
651 const char *reference_name = undef_map->l_name;
653 if (GL(dl_debug_mask) & DL_DEBUG_BINDINGS)
655 INTUSE(_dl_debug_printf) ("binding file %s to %s: %s symbol `%s'",
656 (reference_name[0]
657 ? reference_name
658 : (rtld_progname ?: "<main program>")),
659 value->m->l_name[0]
660 ? value->m->l_name : rtld_progname,
661 protected ? "protected" : "normal",
662 undef_name);
663 if (version)
664 _dl_debug_printf_c (" [%s]\n", version->name);
665 else
666 _dl_debug_printf_c ("\n");
668 #ifdef SHARED
669 if (GL(dl_debug_mask) & DL_DEBUG_PRELINK)
671 int conflict = 0;
672 struct sym_val val = { NULL, NULL };
674 if ((GL(dl_trace_prelink_map) == NULL
675 || GL(dl_trace_prelink_map) == GL(dl_loaded))
676 && undef_map != GL(dl_loaded))
678 const unsigned long int hash = _dl_elf_hash (undef_name);
680 if (version == 0)
681 _dl_do_lookup (undef_name, hash, *ref, &val,
682 undef_map->l_local_scope[0], 0, 0, NULL,
683 type_class);
684 else
685 _dl_do_lookup_versioned (undef_name, hash, *ref, &val,
686 undef_map->l_local_scope[0], 0, version,
687 NULL, type_class);
689 if (val.s != value->s || val.m != value->m)
690 conflict = 1;
693 #ifdef USE_TLS
694 if (value->s
695 && (__builtin_expect (ELFW(ST_TYPE) (value->s->st_info)
696 == STT_TLS, 0)))
697 type_class = 4;
698 #endif
700 if (conflict
701 || GL(dl_trace_prelink_map) == undef_map
702 || GL(dl_trace_prelink_map) == NULL
703 || type_class == 4)
705 _dl_printf ("%s 0x%0*Zx 0x%0*Zx -> 0x%0*Zx 0x%0*Zx ",
706 conflict ? "conflict" : "lookup",
707 (int) sizeof (ElfW(Addr)) * 2, undef_map->l_map_start,
708 (int) sizeof (ElfW(Addr)) * 2,
709 ((ElfW(Addr)) *ref) - undef_map->l_map_start,
710 (int) sizeof (ElfW(Addr)) * 2,
711 (ElfW(Addr)) (value->s ? value->m->l_map_start : 0),
712 (int) sizeof (ElfW(Addr)) * 2,
713 (ElfW(Addr)) (value->s ? value->s->st_value : 0));
715 if (conflict)
716 _dl_printf ("x 0x%0*Zx 0x%0*Zx ",
717 (int) sizeof (ElfW(Addr)) * 2,
718 (ElfW(Addr)) (val.s ? val.m->l_map_start : 0),
719 (int) sizeof (ElfW(Addr)) * 2,
720 (ElfW(Addr)) (val.s ? val.s->st_value : 0));
722 _dl_printf ("/%x %s\n", type_class, undef_name);
725 #endif
728 /* These are here so that we only inline do_lookup{,_versioned} in the common
729 case, not everywhere. */
730 static int __attribute_noinline__
731 internal_function
732 _dl_do_lookup (const char *undef_name, unsigned long int hash,
733 const ElfW(Sym) *ref, struct sym_val *result,
734 struct r_scope_elem *scope, size_t i, int flags,
735 struct link_map *skip, int type_class)
737 return do_lookup (undef_name, hash, ref, result, scope, i, flags, skip,
738 type_class);
741 static int __attribute_noinline__
742 internal_function
743 _dl_do_lookup_versioned (const char *undef_name, unsigned long int hash,
744 const ElfW(Sym) *ref, struct sym_val *result,
745 struct r_scope_elem *scope, size_t i,
746 const struct r_found_version *const version,
747 struct link_map *skip, int type_class)
749 return do_lookup_versioned (undef_name, hash, ref, result, scope, i,
750 version, skip, type_class);