This is the mail archive of the libc-hacker@sources.redhat.com mailing list for the glibc project.
Note that libc-hacker is a closed list. You may look at the archives of this list, but subscription and posting are not open.
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |
Other format: | [Raw text] |
When a dlopened module references a weak symbol from another dlopened module (loaded with RTLD_GLOBAL) no dependency was generated for this fact, so the second module was unloaded even if the first one was still around. I have included patches for both mainline and 2.2 branch. Andreas. 2002-02-17 Andreas Schwab <schwab@suse.de> * elf/dl-lookup.c (_dl_lookup_symbol): Check whether to call add_dependency even if only weak symbols symbols were found. (_dl_lookup_versioned_symbol): Likewise. * reldep7.c, reldep7mod1.c, reldep7mod2.c: New files. * Makefile: Add rules to build and run reldep7. Index: elf/Makefile =================================================================== RCS file: /cvs/glibc/libc/elf/Makefile,v retrieving revision 1.208.2.3 diff -u -a -r1.208.2.3 elf/Makefile --- elf/Makefile 2002/01/08 21:38:17 1.208.2.3 +++ elf/Makefile 2002/02/16 23:18:13 @@ -64,7 +64,7 @@ testobj.h vismod.h globalmod1.c \ dblloadmod1.c dblloadmod2.c dblloadmod3.c \ reldep6mod4.c reldep6mod3.c reldep6mod2.c reldep6mod1.c \ - reldep6mod0.c \ + reldep6mod0.c reldep7mod1.c reldep7mod2.c \ unwind-dw2.c unwind-dw2-fde.c unwind.h unwind-pe.h \ unwind-dw2-fde.h dwarf2.h @@ -116,7 +116,7 @@ reldep reldep2 reldep3 reldep4 $(tests-nodelete-$(have-z-nodelete)) \ $(tests-nodlopen-$(have-z-nodlopen)) neededtest neededtest2 \ neededtest3 neededtest4 unload2 lateglobal initfirst global \ - restest2 next dblload dblunload reldep5 reldep6 + restest2 next dblload dblunload reldep5 reldep6 reldep7 test-srcs = tst-pathopt tests-vis-yes = vismain tests-nodelete-yes = nodelete @@ -133,7 +133,8 @@ neededobj5 neededobj6 firstobj globalmod1 \ unload2mod unload2dep ltglobmod1 ltglobmod2 pathoptobj \ dblloadmod1 dblloadmod2 dblloadmod3 reldepmod5 reldepmod6 \ - reldep6mod0 reldep6mod1 reldep6mod2 reldep6mod3 reldep6mod4 + reldep6mod0 reldep6mod1 reldep6mod2 reldep6mod3 reldep6mod4 \ + reldep7mod1 reldep7mod2 modules-vis-yes = vismod1 vismod2 vismod3 modules-nodelete-yes = nodelmod1 nodelmod2 nodelmod3 nodelmod4 modules-nodlopen-yes = nodlopenmod @@ -446,3 +447,6 @@ $(objpfx)reldep6: $(libdl) $(objpfx)reldep6.out: $(objpfx)reldep6mod3.so $(objpfx)reldep6mod4.so + +$(objpfx)reldep7: $(libdl) +$(objpfx)reldep7.out: $(objpfx)reldep7mod1.so $(objpfx)reldep7mod2.so Index: elf/dl-lookup.c =================================================================== RCS file: /cvs/glibc/libc/elf/dl-lookup.c,v retrieving revision 1.87 diff -u -a -r1.87 elf/dl-lookup.c --- elf/dl-lookup.c 2001/09/08 17:11:36 1.87 +++ elf/dl-lookup.c 2002/02/16 23:18:13 @@ -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,25 +215,8 @@ for (scope = symbol_scope; *scope; ++scope) if (do_lookup (undef_name, hash, *ref, ¤t_value, *scope, 0, 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. */ - && ! explicit - /* 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)) { const char *reference_name = undef_map ? undef_map->l_name : NULL; @@ -250,6 +233,21 @@ return 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. */ + && ! explicit + /* 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); + protected = *ref && ELFW(ST_VISIBILITY) ((*ref)->st_other) == STV_PROTECTED; if (__builtin_expect (_dl_debug_mask & DL_DEBUG_BINDINGS, 0)) @@ -396,25 +394,7 @@ 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. */ - && ! explicit - /* 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) { @@ -457,6 +437,22 @@ *ref = NULL; return 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. */ + && ! explicit + /* 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); protected = *ref && ELFW(ST_VISIBILITY) ((*ref)->st_other) == STV_PROTECTED; Index: elf/reldep7.c =================================================================== RCS file: elf/reldep7.c diff -N elf/reldep7.c --- /dev/null Tue May 5 13:32:27 1998 +++ elf/reldep7.c Sat Feb 16 15:18:13 2002 @@ -0,0 +1,58 @@ +#include <dlfcn.h> +#include <stdio.h> +#include <stdlib.h> + +int +main (void) +{ + void *h1; + void *h2; + void *mod1_bar, *mod2_bar; + + h1 = dlopen ("reldep7mod1.so", RTLD_GLOBAL | RTLD_LAZY); + if (h1 == NULL) + { + printf ("cannot open reldep7mod1.so: %s\n", dlerror ()); + exit (1); + } + + h2 = dlopen ("reldep7mod2.so", RTLD_GLOBAL | RTLD_LAZY); + if (h2 == NULL) + { + printf ("cannot open reldep7mod1.so: %s\n", dlerror ()); + exit (1); + } + + mod1_bar = dlsym (h1, "mod1_bar"); + if (mod1_bar == NULL) + { + printf ("cannot get address of \"mod1_bar\": %s\n", dlerror ()); + exit (1); + } + + mod2_bar = dlsym (h2, "mod2_bar"); + if (mod2_bar == NULL) + { + printf ("cannot get address of \"mod2_bar\": %s\n", dlerror ()); + exit (1); + } + + printf ("%d\n", ((int (*) (void)) mod1_bar) ()); + printf ("%d\n", ((int (*) (void)) mod2_bar) ()); + + if (dlclose (h1) != 0) + { + printf ("closing h1 failed: %s\n", dlerror ()); + exit (1); + } + + printf ("%d\n", ((int (*) (void)) mod2_bar) ()); + + if (dlclose (h2) != 0) + { + printf ("closing h2 failed: %s\n", dlerror ()); + exit (1); + } + + return 0; +} Index: elf/reldep7mod1.c =================================================================== RCS file: elf/reldep7mod1.c diff -N elf/reldep7mod1.c --- /dev/null Tue May 5 13:32:27 1998 +++ elf/reldep7mod1.c Sat Feb 16 15:18:13 2002 @@ -0,0 +1,12 @@ +int foo (void) __attribute__ ((weak)); +int +foo (void) +{ + return 1; +} + +int +mod1_bar (void) +{ + return foo (); +} Index: elf/reldep7mod2.c =================================================================== RCS file: elf/reldep7mod2.c diff -N elf/reldep7mod2.c --- /dev/null Tue May 5 13:32:27 1998 +++ elf/reldep7mod2.c Sat Feb 16 15:18:13 2002 @@ -0,0 +1,12 @@ +int foo (void) __attribute__ ((weak)); +int +foo (void) +{ + return 2; +} + +int +mod2_bar (void) +{ + return foo (); +} ------------------------------------------------------------------------------- Index: elf/Makefile =================================================================== RCS file: /cvs/glibc/libc/elf/Makefile,v retrieving revision 1.223 diff -u -a -r1.223 elf/Makefile --- elf/Makefile 2002/02/14 10:33:21 1.223 +++ elf/Makefile 2002/02/16 23:20:42 @@ -65,7 +65,7 @@ testobj.h vismod.h globalmod1.c \ dblloadmod1.c dblloadmod2.c dblloadmod3.c \ reldep6mod4.c reldep6mod3.c reldep6mod2.c reldep6mod1.c \ - reldep6mod0.c \ + reldep6mod0.c reldep7mod1.c reldep7mod2.c \ unwind-dw2.c unwind-dw2-fde.c unwind.h unwind-pe.h \ unwind-dw2-fde.h dwarf2.h dl-procinfo.c tls.h dl-tls.h \ tls-macros.h @@ -118,8 +118,9 @@ reldep reldep2 reldep3 reldep4 $(tests-nodelete-$(have-z-nodelete)) \ $(tests-nodlopen-$(have-z-nodlopen)) neededtest neededtest2 \ neededtest3 neededtest4 unload2 lateglobal initfirst global \ - restest2 next dblload dblunload reldep5 reldep6 tst-tls1 tst-tls2 \ - tst-tls3 tst-tls4 tst-tls5 tst-tls6 tst-tls7 tst-tls8 + restest2 next dblload dblunload reldep5 reldep6 reldep7 \ + tst-tls1 tst-tls2 tst-tls3 tst-tls4 tst-tls5 tst-tls6 tst-tls7 \ + tst-tls8 test-srcs = tst-pathopt tests-vis-yes = vismain tests-nodelete-yes = nodelete @@ -137,6 +138,7 @@ unload2mod unload2dep ltglobmod1 ltglobmod2 pathoptobj \ dblloadmod1 dblloadmod2 dblloadmod3 reldepmod5 reldepmod6 \ reldep6mod0 reldep6mod1 reldep6mod2 reldep6mod3 reldep6mod4 \ + reldep7mod1 reldep7mod2 \ tst-tlsmod1 tst-tlsmod2 tst-tlsmod3 tst-tlsmod4 modules-vis-yes = vismod1 vismod2 vismod3 modules-nodelete-yes = nodelmod1 nodelmod2 nodelmod3 nodelmod4 @@ -441,6 +443,9 @@ $(objpfx)reldep6: $(libdl) $(objpfx)reldep6.out: $(objpfx)reldep6mod3.so $(objpfx)reldep6mod4.so + +$(objpfx)reldep7: $(libdl) +$(objpfx)reldep7.out: $(objpfx)reldep7mod1.so $(objpfx)reldep7mod2.so $(objpfx)tst-tls3: $(objpfx)tst-tlsmod1.so Index: elf/dl-lookup.c =================================================================== RCS file: /cvs/glibc/libc/elf/dl-lookup.c,v retrieving revision 1.97 diff -u -a -r1.97 elf/dl-lookup.c --- elf/dl-lookup.c 2002/02/11 01:27:01 1.97 +++ elf/dl-lookup.c 2002/02/16 23:20:42 @@ -228,25 +228,8 @@ for (scope = symbol_scope; *scope; ++scope) if (do_lookup (undef_name, hash, *ref, ¤t_value, *scope, 0, 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. */ - && ! explicit - /* 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 INTUSE(_dl_lookup_symbol) (undef_name, undef_map, ref, - symbol_scope, type_class, 0); + break; - break; - } - if (__builtin_expect (current_value.s == NULL, 0)) { const char *reference_name = undef_map ? undef_map->l_name : NULL; @@ -263,6 +246,21 @@ return 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. */ + && ! explicit + /* 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 INTUSE(_dl_lookup_symbol) (undef_name, undef_map, ref, + symbol_scope, type_class, 0); + protected = *ref && ELFW(ST_VISIBILITY) ((*ref)->st_other) == STV_PROTECTED; if (__builtin_expect (protected != 0, 0)) { @@ -390,25 +388,7 @@ 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. */ - && ! explicit - /* 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 INTUSE(_dl_lookup_versioned_symbol) (undef_name, undef_map, - ref, symbol_scope, - version, type_class, 0); - - break; - } + break; if (__builtin_expect (res, 0) < 0) { @@ -451,6 +431,22 @@ *ref = NULL; return 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. */ + && ! explicit + /* 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 INTUSE(_dl_lookup_versioned_symbol) (undef_name, undef_map, + ref, symbol_scope, + version, type_class, 0); protected = *ref && ELFW(ST_VISIBILITY) ((*ref)->st_other) == STV_PROTECTED; Index: elf/reldep7.c =================================================================== RCS file: elf/reldep7.c diff -N elf/reldep7.c --- /dev/null Tue May 5 13:32:27 1998 +++ elf/reldep7.c Sat Feb 16 15:20:42 2002 @@ -0,0 +1,58 @@ +#include <dlfcn.h> +#include <stdio.h> +#include <stdlib.h> + +int +main (void) +{ + void *h1; + void *h2; + void *mod1_bar, *mod2_bar; + + h1 = dlopen ("reldep7mod1.so", RTLD_GLOBAL | RTLD_LAZY); + if (h1 == NULL) + { + printf ("cannot open reldep7mod1.so: %s\n", dlerror ()); + exit (1); + } + + h2 = dlopen ("reldep7mod2.so", RTLD_GLOBAL | RTLD_LAZY); + if (h2 == NULL) + { + printf ("cannot open reldep7mod1.so: %s\n", dlerror ()); + exit (1); + } + + mod1_bar = dlsym (h1, "mod1_bar"); + if (mod1_bar == NULL) + { + printf ("cannot get address of \"mod1_bar\": %s\n", dlerror ()); + exit (1); + } + + mod2_bar = dlsym (h2, "mod2_bar"); + if (mod2_bar == NULL) + { + printf ("cannot get address of \"mod2_bar\": %s\n", dlerror ()); + exit (1); + } + + printf ("%d\n", ((int (*) (void)) mod1_bar) ()); + printf ("%d\n", ((int (*) (void)) mod2_bar) ()); + + if (dlclose (h1) != 0) + { + printf ("closing h1 failed: %s\n", dlerror ()); + exit (1); + } + + printf ("%d\n", ((int (*) (void)) mod2_bar) ()); + + if (dlclose (h2) != 0) + { + printf ("closing h2 failed: %s\n", dlerror ()); + exit (1); + } + + return 0; +} Index: elf/reldep7mod1.c =================================================================== RCS file: elf/reldep7mod1.c diff -N elf/reldep7mod1.c --- /dev/null Tue May 5 13:32:27 1998 +++ elf/reldep7mod1.c Sat Feb 16 15:20:42 2002 @@ -0,0 +1,12 @@ +int foo (void) __attribute__ ((weak)); +int +foo (void) +{ + return 1; +} + +int +mod1_bar (void) +{ + return foo (); +} Index: elf/reldep7mod2.c =================================================================== RCS file: elf/reldep7mod2.c diff -N elf/reldep7mod2.c --- /dev/null Tue May 5 13:32:27 1998 +++ elf/reldep7mod2.c Sat Feb 16 15:20:42 2002 @@ -0,0 +1,12 @@ +int foo (void) __attribute__ ((weak)); +int +foo (void) +{ + return 2; +} + +int +mod2_bar (void) +{ + return foo (); +} -- Andreas Schwab, SuSE Labs, schwab@suse.de SuSE GmbH, Deutschherrnstr. 15-19, D-90429 Nürnberg Key fingerprint = 58CA 54C7 6D53 942B 1756 01D3 44D5 214B 8276 4ED5 "And now for something completely different."
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |