diff --git a/ChangeLog b/ChangeLog index 063ec038ad..2ea9921893 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,15 @@ 2002-09-18 Roland McGrath + * locale/lc-ctype.c (_nl_postload_ctype): Add compat_symbol decls for + the __ctype_* compat symbols, so the relocs generated bind to the + right versioned global symbol in the shared object. + + * elf/do-rel.h (elf_dynamic_do_rel): Mask off 0x8000 bit (hidden flag) + from the value taken from the DT_VERSYM table. + * elf/dl-runtime.c (fixup, profile_fixup): Likewise. + * sysdeps/mips/dl-machine.h (__dl_runtime_resolve): Likewise. + (RESOLVE_GOTSYM): Likewise. + * sysdeps/unix/sysv/linux/sigaction.c (__libc_sigaction): Add libc_hidden_def. * sysdeps/unix/sysv/linux/arm/sigaction.c: Likewise. diff --git a/elf/dl-runtime.c b/elf/dl-runtime.c index 9b24c30841..911c54159b 100644 --- a/elf/dl-runtime.c +++ b/elf/dl-runtime.c @@ -84,7 +84,7 @@ fixup ( { const ElfW(Half) *vernum = (const void *) D_PTR (l, l_info[VERSYMIDX (DT_VERSYM)]); - ElfW(Half) ndx = vernum[ELFW(R_SYM) (reloc->r_info)]; + ElfW(Half) ndx = vernum[ELFW(R_SYM) (reloc->r_info) & 0x7fff]; const struct r_found_version *version = &l->l_versions[ndx]; if (version->hash != 0) @@ -179,7 +179,7 @@ profile_fixup ( { const ElfW(Half) *vernum = (const void *) D_PTR (l,l_info[VERSYMIDX (DT_VERSYM)]); - ElfW(Half) ndx = vernum[ELFW(R_SYM) (reloc->r_info)]; + ElfW(Half) ndx = vernum[ELFW(R_SYM) (reloc->r_info) & 0x7fff]; const struct r_found_version *version = &l->l_versions[ndx]; if (version->hash != 0) diff --git a/elf/do-rel.h b/elf/do-rel.h index bad102549b..c693b6f1e8 100644 --- a/elf/do-rel.h +++ b/elf/do-rel.h @@ -111,7 +111,7 @@ elf_dynamic_do_rel (struct link_map *map, for (; r < end; ++r) { - ElfW(Half) ndx = version[ELFW(R_SYM) (r->r_info)]; + ElfW(Half) ndx = version[ELFW(R_SYM) (r->r_info)] & 0x7fff; elf_machine_rel (map, r, &symtab[ELFW(R_SYM) (r->r_info)], &map->l_versions[ndx], (void *) (l_addr + r->r_offset)); diff --git a/locale/lc-ctype.c b/locale/lc-ctype.c index ad815dfcbf..eb108416d2 100644 --- a/locale/lc-ctype.c +++ b/locale/lc-ctype.c @@ -27,6 +27,8 @@ _NL_CURRENT_DEFINE (LC_CTYPE); /* We are called after loading LC_CTYPE data to load it into the variables used by the ctype.h macros. */ + + void _nl_postload_ctype (void) { @@ -65,6 +67,21 @@ _nl_postload_ctype (void) extern const uint32_t *__ctype32_toupper; extern const uint32_t *__ctype32_tolower; + /* We need the .symver declarations these macros generate so that + our references are explicitly bound to the versioned symbol names + rather than the unadorned names that are not exported. When the + linker sees these bound to local symbols (as the unexported names are) + then it doesn't generate a proper relocation to the global symbols. + We need those relocations so that a versioned definition with a COPY + reloc in an executable will override the libc.so definition. */ + +compat_symbol (libc, __ctype_b, __ctype_b, GLIBC_2_0); +compat_symbol (libc, __ctype_tolower, __ctype_tolower, GLIBC_2_0); +compat_symbol (libc, __ctype_toupper, __ctype_toupper, GLIBC_2_0); +compat_symbol (libc, __ctype32_b, __ctype32_b, GLIBC_2_0); +compat_symbol (libc, __ctype32_tolower, __ctype32_tolower, GLIBC_2_2); +compat_symbol (libc, __ctype32_toupper, __ctype32_toupper, GLIBC_2_2); + __ctype_b = current (uint16_t, CLASS, 128); __ctype_toupper = current (uint32_t, TOUPPER, 128); __ctype_tolower = current (uint32_t, TOLOWER, 128); diff --git a/sysdeps/mips/dl-machine.h b/sysdeps/mips/dl-machine.h index bc5e84fd86..7dbdd794cf 100644 --- a/sysdeps/mips/dl-machine.h +++ b/sysdeps/mips/dl-machine.h @@ -293,7 +293,7 @@ __dl_runtime_resolve (ElfW(Word) sym_index, \ { \ const ElfW(Half) *vernum = \ (const void *) D_PTR (l, l_info[VERSYMIDX (DT_VERSYM)]); \ - ElfW(Half) ndx = vernum[sym_index]; \ + ElfW(Half) ndx = vernum[sym_index & 0x7fff]; \ const struct r_found_version *version = &l->l_versions[ndx]; \ \ if (version->hash != 0) \ @@ -562,7 +562,7 @@ elf_machine_got_rel (struct link_map *map, int lazy) ({ \ const ElfW(Sym) *ref = sym; \ const struct r_found_version *version \ - = vernum ? &map->l_versions[vernum[sym_index]] : NULL; \ + = vernum ? &map->l_versions[vernum[sym_index] & 0x7fff] : NULL; \ ElfW(Addr) value; \ value = RESOLVE (&ref, version, R_MIPS_REL32); \ (ref)? value + ref->st_value: 0; \