From a5312214b7d04443bb7843a0d5b4bbbc070b737a Mon Sep 17 00:00:00 2001 From: Ulrich Drepper Date: Mon, 15 Apr 2002 06:49:02 +0000 Subject: [PATCH] _dl_lookup_symbol): Move add_dependency call to the end of the function. Pass original flags to recursive call if add_dependency failed. (_dl_lookup_versioned_symbol): Likewise. --- elf/dl-lookup.c | 156 ++++++++++++++++++++++-------------------------- 1 file changed, 71 insertions(+), 85 deletions(-) diff --git a/elf/dl-lookup.c b/elf/dl-lookup.c index 6c6b06c5ccd..12cd5f3cba5 100644 --- a/elf/dl-lookup.c +++ b/elf/dl-lookup.c @@ -1,5 +1,5 @@ /* Look up a symbol in the loaded objects. - Copyright (C) 1995,96,97,98,99,2000,2001 Free Software Foundation, Inc. + Copyright (C) 1995,96,97,98,99,2000,2001,2002 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -215,24 +215,7 @@ _dl_lookup_symbol (const char *undef_name, struct link_map *undef_map, for (scope = symbol_scope; *scope; ++scope) if (do_lookup (undef_name, hash, *ref, ¤t_value, *scope, 0, flags, NULL, type_class)) - { - /* We have to check whether this would bind UNDEF_MAP to an object - in the global scope which was dynamically loaded. In this case - we have to prevent the latter from being unloaded unless the - UNDEF_MAP object is also unloaded. */ - if (__builtin_expect (current_value.m->l_type == lt_loaded, 0) - /* Don't do this for explicit lookups as opposed to implicit - runtime lookups. */ - && (flags & DL_LOOKUP_ADD_DEPENDENCY) != 0 - /* Add UNDEF_MAP to the dependencies. */ - && add_dependency (undef_map, current_value.m) < 0) - /* Something went wrong. Perhaps the object we tried to reference - was just removed. Try finding another definition. */ - return _dl_lookup_symbol (undef_name, undef_map, ref, symbol_scope, - type_class, 0); - - break; - } + break; if (__builtin_expect (current_value.s == NULL, 0)) { @@ -251,25 +234,7 @@ _dl_lookup_symbol (const char *undef_name, struct link_map *undef_map, } protected = *ref && ELFW(ST_VISIBILITY) ((*ref)->st_other) == STV_PROTECTED; - - if (__builtin_expect (_dl_debug_mask & DL_DEBUG_BINDINGS, 0)) - { - const char *reference_name = undef_map ? undef_map->l_name : NULL; - - _dl_debug_printf ("binding file %s to %s: %s symbol `%s'\n", - (reference_name && reference_name[0] - ? reference_name : (_dl_argv[0] ?: "
")), - current_value.m->l_name[0] - ? current_value.m->l_name : _dl_argv[0], - protected ? "protected" : "normal", undef_name); - } - - if (__builtin_expect (protected == 0, 1)) - { - *ref = current_value.s; - return LOOKUP_VALUE (current_value.m); - } - else + if (__builtin_expect (protected != 0, 0)) { /* It is very tricky. We need to figure out what value to return for the protected symbol */ @@ -280,14 +245,42 @@ _dl_lookup_symbol (const char *undef_name, struct link_map *undef_map, 0, flags, NULL, ELF_RTYPE_CLASS_PLT)) break; - if (protected_value.s == NULL || protected_value.m == undef_map) + if (protected_value.s != NULL && protected_value.m != undef_map) { - *ref = current_value.s; - return LOOKUP_VALUE (current_value.m); + current_value.s = *ref; + current_value.m = undef_map; } + } - return LOOKUP_VALUE (undef_map); + /* We have to check whether this would bind UNDEF_MAP to an object + in the global scope which was dynamically loaded. In this case + we have to prevent the latter from being unloaded unless the + UNDEF_MAP object is also unloaded. */ + if (__builtin_expect (current_value.m->l_type == lt_loaded, 0) + /* Don't do this for explicit lookups as opposed to implicit + runtime lookups. */ + && (flags & DL_LOOKUP_ADD_DEPENDENCY) != 0 + /* Add UNDEF_MAP to the dependencies. */ + && add_dependency (undef_map, current_value.m) < 0) + /* Something went wrong. Perhaps the object we tried to reference + was just removed. Try finding another definition. */ + return _dl_lookup_symbol (undef_name, undef_map, ref, + symbol_scope, type_class, flags); + + if (__builtin_expect (_dl_debug_mask & DL_DEBUG_BINDINGS, 0)) + { + const char *reference_name = undef_map ? undef_map->l_name : NULL; + + _dl_debug_printf ("binding file %s to %s: %s symbol `%s'\n", + (reference_name && reference_name[0] + ? reference_name : (_dl_argv[0] ?: "
")), + current_value.m->l_name[0] + ? current_value.m->l_name : _dl_argv[0], + protected ? "protected" : "normal", undef_name); } + + *ref = current_value.s; + return LOOKUP_VALUE (current_value.m); } @@ -401,25 +394,7 @@ _dl_lookup_versioned_symbol (const char *undef_name, int res = do_lookup_versioned (undef_name, hash, *ref, ¤t_value, *scope, 0, version, NULL, type_class); if (res > 0) - { - /* We have to check whether this would bind UNDEF_MAP to an object - in the global scope which was dynamically loaded. In this case - we have to prevent the latter from being unloaded unless the - UNDEF_MAP object is also unloaded. */ - if (__builtin_expect (current_value.m->l_type == lt_loaded, 0) - /* Don't do this for explicit lookups as opposed to implicit - runtime lookups. */ - && flags != 0 - /* Add UNDEF_MAP to the dependencies. */ - && add_dependency (undef_map, current_value.m) < 0) - /* Something went wrong. Perhaps the object we tried to reference - was just removed. Try finding another definition. */ - return _dl_lookup_versioned_symbol (undef_name, undef_map, ref, - symbol_scope, version, - type_class, 0); - - break; - } + break; if (__builtin_expect (res, 0) < 0) { @@ -464,26 +439,7 @@ _dl_lookup_versioned_symbol (const char *undef_name, } protected = *ref && ELFW(ST_VISIBILITY) ((*ref)->st_other) == STV_PROTECTED; - - if (__builtin_expect (_dl_debug_mask & DL_DEBUG_BINDINGS, 0)) - { - const char *reference_name = undef_map ? undef_map->l_name : NULL; - - _dl_debug_printf ("binding file %s to %s: %s symbol `%s' [%s]\n", - (reference_name && reference_name[0] - ? reference_name : (_dl_argv[0] ?: "
")), - current_value.m->l_name[0] - ? current_value.m->l_name : _dl_argv[0], - protected ? "protected" : "normal", - undef_name, version->name); - } - - if (__builtin_expect (protected == 0, 1)) - { - *ref = current_value.s; - return LOOKUP_VALUE (current_value.m); - } - else + if (__builtin_expect (protected != 0, 0)) { /* It is very tricky. We need to figure out what value to return for the protected symbol */ @@ -495,14 +451,44 @@ _dl_lookup_versioned_symbol (const char *undef_name, ELF_RTYPE_CLASS_PLT)) break; - if (protected_value.s == NULL || protected_value.m == undef_map) + if (protected_value.s != NULL && protected_value.m != undef_map) { - *ref = current_value.s; - return LOOKUP_VALUE (current_value.m); + current_value.s = *ref; + current_value.m = undef_map; } + } - return LOOKUP_VALUE (undef_map); + /* We have to check whether this would bind UNDEF_MAP to an object + in the global scope which was dynamically loaded. In this case + we have to prevent the latter from being unloaded unless the + UNDEF_MAP object is also unloaded. */ + if (__builtin_expect (current_value.m->l_type == lt_loaded, 0) + /* Don't do this for explicit lookups as opposed to implicit + runtime lookups. */ + && flags != 0 + /* Add UNDEF_MAP to the dependencies. */ + && add_dependency (undef_map, current_value.m) < 0) + /* Something went wrong. Perhaps the object we tried to reference + was just removed. Try finding another definition. */ + return _dl_lookup_versioned_symbol (undef_name, undef_map, ref, + symbol_scope, version, type_class, + flags); + + if (__builtin_expect (_dl_debug_mask & DL_DEBUG_BINDINGS, 0)) + { + const char *reference_name = undef_map ? undef_map->l_name : NULL; + + _dl_debug_printf ("binding file %s to %s: %s symbol `%s' [%s]\n", + (reference_name && reference_name[0] + ? reference_name : (_dl_argv[0] ?: "
")), + current_value.m->l_name[0] + ? current_value.m->l_name : _dl_argv[0], + protected ? "protected" : "normal", + undef_name, version->name); } + + *ref = current_value.s; + return LOOKUP_VALUE (current_value.m); } -- 2.47.2