1 /* Look up a symbol in the loaded objects.
2 Copyright (C) 1995-2002, 2003, 2004 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 <bits/libc-lock.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: ";
46 #define make_string(string, rest...) \
48 const char *all[] = { string, ## rest }; \
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]); \
63 /* Statistics function. */
65 # define bump_num_relocations() ++GL(dl_num_relocations)
67 # define bump_num_relocations() ((void) 0)
71 /* The actual lookup code. */
72 #include "do-lookup.h"
75 /* Add extra dependency on MAP to UNDEF_MAP. */
78 add_dependency (struct link_map
*undef_map
, struct link_map
*map
)
80 struct link_map
**list
;
81 struct link_map
*runp
;
86 /* Avoid self-references and references to objects which cannot be
91 /* Make sure nobody can unload the object while we are at it. */
92 __rtld_lock_lock_recursive (GL(dl_load_lock
));
94 /* Don't create cross-reference between modules which are
95 dynamically loaded by the same dlopen() call. */
96 if (undef_map
->l_opencount
== 0 && map
->l_opencount
== 0)
99 /* Avoid references to objects which cannot be unloaded anyway. */
100 if (map
->l_type
!= lt_loaded
101 || (map
->l_flags_1
& DF_1_NODELETE
) != 0)
104 /* If the object with the undefined reference cannot be removed ever
105 just make sure the same is true for the object which contains the
107 if (undef_map
->l_type
!= lt_loaded
108 || (undef_map
->l_flags_1
& DF_1_NODELETE
) != 0)
111 map
->l_flags_1
|= DF_1_NODELETE
;
115 /* Determine whether UNDEF_MAP already has a reference to MAP. First
116 look in the normal dependencies. */
117 if (undef_map
->l_searchlist
.r_list
!= NULL
)
119 list
= undef_map
->l_initfini
;
121 for (i
= 0; list
[i
] != NULL
; ++i
)
126 /* No normal dependency. See whether we already had to add it
127 to the special list of dynamic dependencies. */
128 list
= undef_map
->l_reldeps
;
129 act
= undef_map
->l_reldepsact
;
131 for (i
= 0; i
< act
; ++i
)
135 /* The object is not yet in the dependency list. Before we add
136 it make sure just one more time the object we are about to
137 reference is still available. There is a brief period in
138 which the object could have been removed since we found the
140 runp
= GL(dl_loaded
);
141 while (runp
!= NULL
&& runp
!= map
)
146 /* The object is still available. Add the reference now. */
147 if (__builtin_expect (act
>= undef_map
->l_reldepsmax
, 0))
149 /* Allocate more memory for the dependency list. Since this
150 can never happen during the startup phase we can use
154 undef_map
->l_reldepsmax
+= 5;
155 newp
= realloc (undef_map
->l_reldeps
,
156 undef_map
->l_reldepsmax
157 * sizeof (struct link_map
*));
159 if (__builtin_expect (newp
!= NULL
, 1))
160 undef_map
->l_reldeps
= (struct link_map
**) newp
;
162 /* Correct the addition. */
163 undef_map
->l_reldepsmax
-= 5;
166 /* If we didn't manage to allocate memory for the list this is
167 no fatal mistake. We simply increment the use counter of the
168 referenced object and don't record the dependencies. This
169 means this increment can never be reverted and the object
170 will never be unloaded. This is semantically the correct
172 if (__builtin_expect (act
< undef_map
->l_reldepsmax
, 1))
173 undef_map
->l_reldeps
[undef_map
->l_reldepsact
++] = map
;
175 if (map
->l_searchlist
.r_list
!= NULL
)
176 /* And increment the counter in the referenced object. */
179 /* We have to bump the counts for all dependencies since so far
180 this object was only a normal or transitive dependency.
181 Now it might be closed with _dl_close() directly. */
182 for (list
= map
->l_initfini
; *list
!= NULL
; ++list
)
183 ++(*list
)->l_opencount
;
185 /* Display information if we are debugging. */
186 if (__builtin_expect (GLRO(dl_debug_mask
) & DL_DEBUG_FILES
, 0))
188 \nfile=%s; needed by %s (relocation dependency)\n\n",
189 map
->l_name
[0] ? map
->l_name
: rtld_progname
,
191 ? undef_map
->l_name
: rtld_progname
);
194 /* Whoa, that was bad luck. We have to search again. */
198 /* Release the lock. */
199 __rtld_lock_unlock_recursive (GL(dl_load_lock
));
206 _dl_debug_bindings (const char *undef_name
, struct link_map
*undef_map
,
207 const ElfW(Sym
) **ref
, struct r_scope_elem
*symbol_scope
[],
208 struct sym_val
*value
,
209 const struct r_found_version
*version
, int type_class
,
213 /* Search loaded objects' symbol tables for a definition of the symbol
214 UNDEF_NAME, perhaps with a requested version for the symbol. */
217 _dl_lookup_symbol_x (const char *undef_name
, struct link_map
*undef_map
,
218 const ElfW(Sym
) **ref
,
219 struct r_scope_elem
*symbol_scope
[],
220 const struct r_found_version
*version
,
221 int type_class
, int flags
, struct link_map
*skip_map
)
223 const unsigned long int hash
= _dl_elf_hash (undef_name
);
224 struct sym_val current_value
= { NULL
, NULL
};
225 struct r_scope_elem
**scope
= symbol_scope
;
227 bump_num_relocations ();
229 /* No other flag than DL_LOOKUP_ADD_DEPENDENCY is allowed if we look
230 up a versioned symbol. */
231 assert (version
== NULL
|| flags
== 0 || flags
== DL_LOOKUP_ADD_DEPENDENCY
);
234 if (__builtin_expect (skip_map
!= NULL
, 0))
236 /* Search the relevant loaded objects for a definition. */
237 while ((*scope
)->r_list
[i
] != skip_map
)
240 assert (i
< (*scope
)->r_nlist
);
243 /* Search the relevant loaded objects for a definition. */
244 for (size_t start
= i
; *scope
!= NULL
; start
= 0, ++scope
)
246 int res
= do_lookup_x (undef_name
, hash
, *ref
, ¤t_value
, *scope
,
247 start
, version
, flags
, skip_map
, type_class
);
251 if (__builtin_expect (res
, 0) < 0 && skip_map
== NULL
)
253 /* Oh, oh. The file named in the relocation entry does not
254 contain the needed symbol. This code is never reached
255 for unversioned lookups. */
256 assert (version
!= NULL
);
257 const char *reference_name
= undef_map
? undef_map
->l_name
: NULL
;
259 /* XXX We cannot translate the message. */
260 _dl_signal_cerror (0, (reference_name
[0]
262 : (rtld_progname
?: "<main program>")),
263 N_("relocation error"),
264 make_string ("symbol ", undef_name
, ", version ",
266 " not defined in file ",
268 " with link time reference",
270 ? " (no version symbols)" : ""));
276 if (__builtin_expect (current_value
.s
== NULL
, 0))
278 if ((*ref
== NULL
|| ELFW(ST_BIND
) ((*ref
)->st_info
) != STB_WEAK
)
281 /* We could find no value for a strong reference. */
282 const char *reference_name
= undef_map
? undef_map
->l_name
: "";
283 const char *versionstr
= version
? ", version " : "";
284 const char *versionname
= (version
&& version
->name
285 ? version
->name
: "");
287 /* XXX We cannot translate the message. */
288 _dl_signal_cerror (0, (reference_name
[0]
290 : (rtld_progname
?: "<main program>")),
291 N_("symbol lookup error"),
292 make_string (undefined_msg
, undef_name
,
293 versionstr
, versionname
));
299 int protected = (*ref
300 && ELFW(ST_VISIBILITY
) ((*ref
)->st_other
) == STV_PROTECTED
);
301 if (__builtin_expect (protected != 0, 0))
303 /* It is very tricky. We need to figure out what value to
304 return for the protected symbol. */
305 if (type_class
== ELF_RTYPE_CLASS_PLT
)
307 if (current_value
.s
!= NULL
&& current_value
.m
!= undef_map
)
309 current_value
.s
= *ref
;
310 current_value
.m
= undef_map
;
315 struct sym_val protected_value
= { NULL
, NULL
};
317 for (scope
= symbol_scope
; *scope
!= NULL
; i
= 0, ++scope
)
318 if (do_lookup_x (undef_name
, hash
, *ref
, &protected_value
,
319 *scope
, i
, version
, flags
, skip_map
,
320 ELF_RTYPE_CLASS_PLT
) != 0)
323 if (protected_value
.s
!= NULL
&& protected_value
.m
!= undef_map
)
325 current_value
.s
= *ref
;
326 current_value
.m
= undef_map
;
331 /* We have to check whether this would bind UNDEF_MAP to an object
332 in the global scope which was dynamically loaded. In this case
333 we have to prevent the latter from being unloaded unless the
334 UNDEF_MAP object is also unloaded. */
335 if (__builtin_expect (current_value
.m
->l_type
== lt_loaded
, 0)
336 /* Don't do this for explicit lookups as opposed to implicit
338 && (flags
& DL_LOOKUP_ADD_DEPENDENCY
) != 0
339 /* Add UNDEF_MAP to the dependencies. */
340 && add_dependency (undef_map
, current_value
.m
) < 0)
341 /* Something went wrong. Perhaps the object we tried to reference
342 was just removed. Try finding another definition. */
343 return _dl_lookup_symbol_x (undef_name
, undef_map
, ref
,
344 symbol_scope
, version
, type_class
,
347 if (__builtin_expect (GLRO(dl_debug_mask
)
348 & (DL_DEBUG_BINDINGS
|DL_DEBUG_PRELINK
), 0))
349 _dl_debug_bindings (undef_name
, undef_map
, ref
, symbol_scope
,
350 ¤t_value
, version
, type_class
, protected);
352 *ref
= current_value
.s
;
353 return LOOKUP_VALUE (current_value
.m
);
357 /* Cache the location of MAP's hash table. */
361 _dl_setup_hash (struct link_map
*map
)
366 if (!map
->l_info
[DT_HASH
])
368 hash
= (void *) D_PTR (map
, l_info
[DT_HASH
]);
370 map
->l_nbuckets
= *hash
++;
372 map
->l_buckets
= hash
;
373 hash
+= map
->l_nbuckets
;
380 _dl_debug_bindings (const char *undef_name
, struct link_map
*undef_map
,
381 const ElfW(Sym
) **ref
, struct r_scope_elem
*symbol_scope
[],
382 struct sym_val
*value
,
383 const struct r_found_version
*version
, int type_class
,
386 const char *reference_name
= undef_map
->l_name
;
388 if (GLRO(dl_debug_mask
) & DL_DEBUG_BINDINGS
)
390 _dl_debug_printf ("binding file %s to %s: %s symbol `%s'",
393 : (rtld_progname
?: "<main program>")),
394 value
->m
->l_name
[0] ? value
->m
->l_name
: rtld_progname
,
395 protected ? "protected" : "normal", undef_name
);
397 _dl_debug_printf_c (" [%s]\n", version
->name
);
399 _dl_debug_printf_c ("\n");
402 if (GLRO(dl_debug_mask
) & DL_DEBUG_PRELINK
)
405 struct sym_val val
= { NULL
, NULL
};
407 if ((GLRO(dl_trace_prelink_map
) == NULL
408 || GLRO(dl_trace_prelink_map
) == GL(dl_loaded
))
409 && undef_map
!= GL(dl_loaded
))
411 const unsigned long int hash
= _dl_elf_hash (undef_name
);
413 do_lookup_x (undef_name
, hash
, *ref
, &val
,
414 undef_map
->l_local_scope
[0], 0, version
, 0, NULL
,
417 if (val
.s
!= value
->s
|| val
.m
!= value
->m
)
423 && (__builtin_expect (ELFW(ST_TYPE
) (value
->s
->st_info
)
429 || GLRO(dl_trace_prelink_map
) == undef_map
430 || GLRO(dl_trace_prelink_map
) == NULL
433 _dl_printf ("%s 0x%0*Zx 0x%0*Zx -> 0x%0*Zx 0x%0*Zx ",
434 conflict
? "conflict" : "lookup",
435 (int) sizeof (ElfW(Addr
)) * 2,
436 (size_t) undef_map
->l_map_start
,
437 (int) sizeof (ElfW(Addr
)) * 2,
438 (size_t) (((ElfW(Addr
)) *ref
) - undef_map
->l_map_start
),
439 (int) sizeof (ElfW(Addr
)) * 2,
440 (size_t) (value
->s
? value
->m
->l_map_start
: 0),
441 (int) sizeof (ElfW(Addr
)) * 2,
442 (size_t) (value
->s
? value
->s
->st_value
: 0));
445 _dl_printf ("x 0x%0*Zx 0x%0*Zx ",
446 (int) sizeof (ElfW(Addr
)) * 2,
447 (size_t) (val
.s
? val
.m
->l_map_start
: 0),
448 (int) sizeof (ElfW(Addr
)) * 2,
449 (size_t) (val
.s
? val
.s
->st_value
: 0));
451 _dl_printf ("/%x %s\n", type_class
, undef_name
);