This is the mail archive of the libc-hacker@sourceware.cygnus.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] |
This patch may not be 100% correct. But it passed all the visibility tests in today's binutils from CVS. -- H.J. Lu (hjl@gnu.org) -- 2000-05-21 2000 H.J. Lu <hjl@gnu.org> * elf/do-lookup.h (do_lookup_protected_versioned): New. Used by the STV_PROTECTED support. (do_lookup_protected): Likewise. * elf/dl-lookup.c (_dl_lookup_symbol): Support STV_PROTECTED. (_dl_lookup_symbol_skip): Likewise. (_dl_lookup_versioned_symbol): Likewise. (_dl_lookup_versioned_symbol_skip): Likewise. * elf/dl-reloc.c (RESOLVE): Check STB_LOCAL instead of ST_VISIBILITY. * elf/dl-runtime.c (profile_fixup): Fix a typo in comment. Index: elf/dl-lookup.c =================================================================== RCS file: /work/cvs/gnu/glibc/elf/dl-lookup.c,v retrieving revision 1.1.1.1 diff -u -p -r1.1.1.1 dl-lookup.c --- elf/dl-lookup.c 2000/05/21 21:10:57 1.1.1.1 +++ elf/dl-lookup.c 2000/05/21 21:41:28 @@ -75,9 +75,19 @@ __libc_lock_define (extern, _dl_load_loc without versioning. gcc is not able to optimize a single function definition serving for both purposes so we define two functions. */ #define VERSIONED 0 +#define PROTECTED 0 #include "do-lookup.h" +#define VERSIONED 0 +#define PROTECTED 1 +#include "do-lookup.h" + +#define VERSIONED 1 +#define PROTECTED 0 +#include "do-lookup.h" + #define VERSIONED 1 +#define PROTECTED 1 #include "do-lookup.h" @@ -194,6 +204,7 @@ _dl_lookup_symbol (const char *undef_nam const unsigned long int hash = _dl_elf_hash (undef_name); struct sym_val current_value = { NULL, NULL }; struct r_scope_elem **scope; + int protected; ++_dl_num_relocations; @@ -232,6 +243,8 @@ _dl_lookup_symbol (const char *undef_nam return 0; } + protected = *ref && ELFW(ST_VISIBILITY) ((*ref)->st_other) + == STV_PROTECTED; if (__builtin_expect (_dl_debug_bindings, 0)) _dl_debug_message (1, "binding file ", (reference_name && reference_name[0] @@ -239,10 +252,34 @@ _dl_lookup_symbol (const char *undef_nam : (_dl_argv[0] ?: "<main program>")), " to ", current_value.m->l_name[0] ? current_value.m->l_name : _dl_argv[0], - ": symbol `", undef_name, "'\n", NULL); + ": ", protected ? "protected" : "normal", + " symbol `", undef_name, "'\n", NULL); + + if (__builtin_expect (protected == 0, 1)) + { + *ref = current_value.s; + return LOOKUP_VALUE (current_value.m); + } + else + { + /* It is very tricky. We need to figure out what value to + return for the protected symbol */ + struct sym_val protected_value = { NULL, NULL }; + + for (scope = symbol_scope; *scope; ++scope) + if (do_lookup_protected (undef_name, undef_map, hash, *ref, + &protected_value, *scope, 0, NULL, + reloc_type)) + break; - *ref = current_value.s; - return LOOKUP_VALUE (current_value.m); + if (protected_value.s == NULL || protected_value.m == undef_map) + { + *ref = current_value.s; + return LOOKUP_VALUE (current_value.m); + } + else + return LOOKUP_VALUE (undef_map); + } } @@ -263,6 +300,7 @@ _dl_lookup_symbol_skip (const char *unde struct sym_val current_value = { NULL, NULL }; struct r_scope_elem **scope; size_t i; + int protected; ++_dl_num_relocations; @@ -319,6 +357,8 @@ _dl_lookup_symbol_skip (const char *unde return 0; } + protected = *ref && ELFW(ST_VISIBILITY) ((*ref)->st_other) + == STV_PROTECTED; if (__builtin_expect (_dl_debug_bindings, 0)) _dl_debug_message (1, "binding file ", (reference_name && reference_name[0] @@ -326,10 +366,38 @@ _dl_lookup_symbol_skip (const char *unde : (_dl_argv[0] ?: "<main program>")), " to ", current_value.m->l_name[0] ? current_value.m->l_name : _dl_argv[0], - ": symbol `", undef_name, "' (skip)\n", NULL); + ": ", protected ? "protected" : "normal", + " symbol `", undef_name, "'\n", NULL); + + if (__builtin_expect (protected == 0, 1)) + { + *ref = current_value.s; + return LOOKUP_VALUE (current_value.m); + } + else + { + /* It is very tricky. We need to figure out what value to + return for the protected symbol */ + struct sym_val protected_value = { NULL, NULL }; + + if (i >= (*scope)->r_nlist + || !do_lookup_protected (undef_name, undef_map, hash, *ref, + &protected_value, *scope, i, + skip_map, 0)) + while (*++scope) + if (do_lookup_protected (undef_name, undef_map, hash, *ref, + &protected_value, *scope, 0, + skip_map, 0)) + break; - *ref = current_value.s; - return LOOKUP_VALUE (current_value.m); + if (protected_value.s == NULL || protected_value.m == undef_map) + { + *ref = current_value.s; + return LOOKUP_VALUE (current_value.m); + } + else + return LOOKUP_VALUE (undef_map); + } } @@ -350,6 +418,7 @@ _dl_lookup_versioned_symbol (const char const unsigned long int hash = _dl_elf_hash (undef_name); struct sym_val current_value = { NULL, NULL }; struct r_scope_elem **scope; + int protected; ++_dl_num_relocations; @@ -412,6 +481,8 @@ _dl_lookup_versioned_symbol (const char return 0; } + protected = *ref && ELFW(ST_VISIBILITY) ((*ref)->st_other) + == STV_PROTECTED; if (__builtin_expect (_dl_debug_bindings, 0)) _dl_debug_message (1, "binding file ", (reference_name && reference_name[0] @@ -419,11 +490,36 @@ _dl_lookup_versioned_symbol (const char : (_dl_argv[0] ?: "<main program>")), " to ", current_value.m->l_name[0] ? current_value.m->l_name : _dl_argv[0], - ": symbol `", undef_name, "' [", version->name, + ": ", protected ? "protected" : "normal", + " symbol `", undef_name, "' [", version->name, "]\n", NULL); + + if (__builtin_expect (protected == 0, 1)) + { + *ref = current_value.s; + return LOOKUP_VALUE (current_value.m); + } + else + { + /* It is very tricky. We need to figure out what value to + return for the protected symbol */ + struct sym_val protected_value = { NULL, NULL }; + + for (scope = symbol_scope; *scope; ++scope) + if (do_lookup_protected_versioned (undef_name, undef_map, hash, + *ref, &protected_value, + *scope, 0, version, NULL, + reloc_type)) + break; - *ref = current_value.s; - return LOOKUP_VALUE (current_value.m); + if (protected_value.s == NULL || protected_value.m == undef_map) + { + *ref = current_value.s; + return LOOKUP_VALUE (current_value.m); + } + else + return LOOKUP_VALUE (undef_map); + } } @@ -443,6 +539,7 @@ _dl_lookup_versioned_symbol_skip (const struct sym_val current_value = { NULL, NULL }; struct r_scope_elem **scope; size_t i; + int protected; ++_dl_num_relocations; @@ -512,19 +609,50 @@ _dl_lookup_versioned_symbol_skip (const return 0; } + protected = *ref && ELFW(ST_VISIBILITY) ((*ref)->st_other) + == STV_PROTECTED; if (__builtin_expect (_dl_debug_bindings, 0)) _dl_debug_message (1, "binding file ", (reference_name && reference_name[0] ? reference_name : (_dl_argv[0] ?: "<main program>")), - " to ", - current_value.m->l_name[0] + " to ", current_value.m->l_name[0] ? current_value.m->l_name : _dl_argv[0], - ": symbol `", undef_name, "' [", version->name, - "] (skip)\n", NULL); + ": ", protected ? "protected" : "normal", + " symbol `", undef_name, "' [", version->name, + "]\n", NULL); + + if (__builtin_expect (protected == 0, 1)) + { + *ref = current_value.s; + return LOOKUP_VALUE (current_value.m); + } + else + { + /* It is very tricky. We need to figure out what value to + return for the protected symbol */ + struct sym_val protected_value = { NULL, NULL }; + + if (i >= (*scope)->r_nlist + || !do_lookup_protected_versioned (undef_name, undef_map, + hash, *ref, + &protected_value, *scope, + i, version, skip_map, 0)) + while (*++scope) + if (do_lookup_protected_versioned (undef_name, undef_map, + hash, *ref, + &protected_value, *scope, + 0, version, skip_map, 0)) + break; - *ref = current_value.s; - return LOOKUP_VALUE (current_value.m); + if (protected_value.s == NULL || protected_value.m == undef_map) + { + *ref = current_value.s; + return LOOKUP_VALUE (current_value.m); + } + else + return LOOKUP_VALUE (undef_map); + } } Index: elf/dl-reloc.c =================================================================== RCS file: /work/cvs/gnu/glibc/elf/dl-reloc.c,v retrieving revision 1.1.1.1 diff -u -p -r1.1.1.1 dl-reloc.c --- elf/dl-reloc.c 2000/05/21 21:10:57 1.1.1.1 +++ elf/dl-reloc.c 2000/05/21 21:35:12 @@ -79,7 +79,7 @@ _dl_relocate_object (struct link_map *l, (flags))) \ : l) #define RESOLVE(ref, version, flags) \ - (__builtin_expect (ELFW(ST_VISIBILITY) ((*ref)->st_other), 0) == 0 \ + (ELFW(ST_BIND) ((*ref)->st_info) != STB_LOCAL \ ? ((version) != NULL && (version)->hash != 0 \ ? _dl_lookup_versioned_symbol (strtab + (*ref)->st_name, l, (ref), \ scope, (version), (flags)) \ Index: elf/dl-runtime.c =================================================================== RCS file: /work/cvs/gnu/glibc/elf/dl-runtime.c,v retrieving revision 1.1.1.1 diff -u -p -r1.1.1.1 dl-runtime.c --- elf/dl-runtime.c 2000/05/21 21:10:57 1.1.1.1 +++ elf/dl-runtime.c 2000/05/21 21:36:44 @@ -158,7 +158,7 @@ profile_fixup ( /* Sanity check that we're really looking at a PLT relocation. */ assert (ELFW(R_TYPE)(reloc->r_info) == ELF_MACHINE_JMP_SLOT); - /* Look up the target symbol. If the symbol is marked STV_PROTEXTED + /* Look up the target symbol. If the symbol is marked STV_PROTECTED don't look in the global scope. */ if (__builtin_expect (ELFW(ST_VISIBILITY) (sym->st_other), 0) == 0) { Index: elf/do-lookup.h =================================================================== RCS file: /work/cvs/gnu/glibc/elf/do-lookup.h,v retrieving revision 1.1.1.1 diff -u -p -r1.1.1.1 do-lookup.h --- elf/do-lookup.h 2000/05/21 21:10:58 1.1.1.1 +++ elf/do-lookup.h 2000/05/21 21:26:35 @@ -18,10 +18,18 @@ Boston, MA 02111-1307, USA. */ #if VERSIONED -# define FCT do_lookup_versioned +# if PROTECTED +# define FCT do_lookup_protected_versioned +# else +# define FCT do_lookup_versioned +# endif # define ARG const struct r_found_version *const version, #else -# define FCT do_lookup +# if PROTECTED +# define FCT do_lookup_protected +# else +# define FCT do_lookup +# endif # define ARG #endif @@ -56,10 +64,12 @@ FCT (const char *undef_name, struct link if (skip != NULL && map == skip) continue; +#if !PROTECTED /* Don't search the executable when resolving a copy reloc. */ if (elf_machine_lookup_noexec_p (reloc_type) && map->l_type == lt_executable) continue; +#endif /* Print some debugging info if wanted. */ if (_dl_debug_symbols) @@ -80,8 +90,13 @@ FCT (const char *undef_name, struct link sym = &symtab[symidx]; if (sym->st_value == 0 || /* No value. */ +#if PROTECTED + sym->st_shndx == SHN_UNDEF +#else (elf_machine_lookup_noplt_p (reloc_type) /* Reject PLT entry. */ - && sym->st_shndx == SHN_UNDEF)) + && sym->st_shndx == SHN_UNDEF) +#endif + ) continue; if (ELFW(ST_TYPE) (sym->st_info) > STT_FUNC) @@ -154,12 +169,7 @@ FCT (const char *undef_name, struct link sym = num_versions == 1 ? versioned_sym : NULL; #endif - if (sym != NULL - /* Don't allow binding if the symbol is hidden. When processor - specific definitions for STV_INTERNAL are defined we might - have to extend this conditional. */ - && (ELFW(ST_VISIBILITY) (sym->st_other) != STV_HIDDEN - || map == undef_map)) + if (sym != NULL) { found_it: switch (ELFW(ST_BIND) (sym->st_info)) @@ -199,4 +209,5 @@ FCT (const char *undef_name, struct link #undef FCT #undef ARG +#undef PROTECTED #undef VERSIONED
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |