diff options
-rw-r--r-- | ChangeLog | 17 | ||||
-rw-r--r-- | elf/dl-addr.c | 15 | ||||
-rw-r--r-- | sysdeps/generic/ldsodefs.h | 10 | ||||
-rw-r--r-- | sysdeps/ieee754/flt-32/e_hypotf.c | 4 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/powerpc/powerpc64/ldsodefs.h | 77 |
5 files changed, 109 insertions, 14 deletions
@@ -1,3 +1,20 @@ +2005-08-30 Ulrich Drepper <drepper@redhat.com> + + * sysdeps/ieee754/flt-32/e_hypotf.c [!__STDC__]: Fix function name. + +2005-08-01 Bob Wilson <bob.wilson@acm.org> + Richard Sandiford <richard@codesourcery.com> + + * sysdeps/ieee754/flt-32/e_hypotf.c (__ieee754_hypotf): Add missing + exponent bias to the value for 2^126. + +2005-08-30 Jakub Jelinek <jakub@redhat.com> + Alan Modra <amodra@bigpond.net.au> + + * elf/dl-addr.c (_dl_addr): Use DL_ADDR_SYM_MATCH macro. + * sysdeps/generic/ldsodefs.h (DL_ADDR_SYM_MATCH): Define. + * sysdeps/unix/sysv/linux/powerpc/powerpc64/ldsodefs.h: New file. + 2005-08-23 Ulrich Drepper <drepper@redhat.com> * nscd/nscd.c (main): Use error while process isn't running in the diff --git a/elf/dl-addr.c b/elf/dl-addr.c index 6bd7f7b..fa62e40 100644 --- a/elf/dl-addr.c +++ b/elf/dl-addr.c @@ -85,22 +85,15 @@ _dl_addr (const void *address, Dl_info *info, the string table which generally follows the symbol table. */ symtabend = (const ElfW(Sym) *) strtab; - /* We assume that the string table follows the symbol table, - because there is no way in ELF to know the size of the - dynamic symbol table!! */ const ElfW(Sym) *matchsym; for (matchsym = NULL; (void *) symtab < (void *) symtabend; ++symtab) - if (addr >= match->l_addr + symtab->st_value + if ((ELFW(ST_BIND) (symtab->st_info) == STB_GLOBAL + || ELFW(ST_BIND) (symtab->st_info) == STB_WEAK) #if defined USE_TLS && ELFW(ST_TYPE) (symtab->st_info) != STT_TLS #endif - && ((symtab->st_size == 0 - && addr == match->l_addr + symtab->st_value) - || addr < match->l_addr + symtab->st_value + symtab->st_size) - && symtab->st_name < strtabsize - && (matchsym == NULL || matchsym->st_value < symtab->st_value) - && (ELFW(ST_BIND) (symtab->st_info) == STB_GLOBAL - || ELFW(ST_BIND) (symtab->st_info) == STB_WEAK)) + && DL_ADDR_SYM_MATCH (match, symtab, matchsym, addr) + && symtab->st_name < strtabsize) matchsym = (ElfW(Sym) *) symtab; if (mapp) diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h index a24c2ff..191ae4d 100644 --- a/sysdeps/generic/ldsodefs.h +++ b/sysdeps/generic/ldsodefs.h @@ -62,7 +62,7 @@ typedef struct link_map *lookup_t; # define LOOKUP_VALUE(map) map # define LOOKUP_VALUE_ADDRESS(map) ((map) ? (map)->l_addr : 0) -/* on some architectures a pointer to a function is not just a pointer +/* On some architectures a pointer to a function is not just a pointer to the actual code of the function but rather an architecture specific descriptor. */ #ifndef ELF_FUNCTION_PTR_IS_SPECIAL @@ -73,6 +73,14 @@ typedef struct link_map *lookup_t; # define DL_DT_FINI_ADDRESS(map, start) (start) #endif +/* On some architectures dladdr can't use st_size of all symbols this way. */ +#define DL_ADDR_SYM_MATCH(L, SYM, MATCHSYM, ADDR) \ + ((ADDR) >= (L)->l_addr + (SYM)->st_value \ + && (((SYM)->st_size == 0 \ + && (ADDR) == (L)->l_addr + (SYM)->st_value) \ + || (ADDR) < (L)->l_addr + (SYM)->st_value + (SYM)->st_size) \ + && ((MATCHSYM) == NULL || (MATCHSYM)->st_value < (SYM)->st_value)) + /* Unmap a loaded object, called by _dl_close (). */ #ifndef DL_UNMAP_IS_SPECIAL # define DL_UNMAP(map) \ diff --git a/sysdeps/ieee754/flt-32/e_hypotf.c b/sysdeps/ieee754/flt-32/e_hypotf.c index d6b1520..ddcd8ee 100644 --- a/sysdeps/ieee754/flt-32/e_hypotf.c +++ b/sysdeps/ieee754/flt-32/e_hypotf.c @@ -23,7 +23,7 @@ static char rcsid[] = "$NetBSD: e_hypotf.c,v 1.5 1995/05/12 04:57:30 jtc Exp $"; #ifdef __STDC__ float __ieee754_hypotf(float x, float y) #else - float __ieee754_hypot(x,y) + float __ieee754_hypotf(x,y) float x, y; #endif { @@ -54,7 +54,7 @@ static char rcsid[] = "$NetBSD: e_hypotf.c,v 1.5 1995/05/12 04:57:30 jtc Exp $"; if(hb < 0x26800000) { /* b < 2**-50 */ if(hb <= 0x007fffff) { /* subnormal b or 0 */ if(hb==0) return a; - SET_FLOAT_WORD(t1,0x3f000000); /* t1=2^126 */ + SET_FLOAT_WORD(t1,0x7e800000); /* t1=2^126 */ b *= t1; a *= t1; k -= 126; diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/ldsodefs.h b/sysdeps/unix/sysv/linux/powerpc/powerpc64/ldsodefs.h new file mode 100644 index 0000000..1ead3dd --- /dev/null +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/ldsodefs.h @@ -0,0 +1,77 @@ +/* Run-time dynamic linker data structures for loaded ELF shared objects. + Copyright (C) 2005 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 + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#ifndef _LDSODEFS_H + +/* Get the real definitions. */ +#include_next <ldsodefs.h> + +/* Now define our stuff. */ + +static __always_inline bool +_dl_ppc64_is_opd_sym (const struct link_map *l, const ElfW(Sym) *sym) +{ + return (ELFW(ST_TYPE) (sym->st_info) == STT_FUNC + && l->l_addr + sym->st_value >= (ElfW(Addr)) l->l_ld + && l->l_addr + sym->st_value < l->l_map_end + && sym->st_size != 0); +} + +static __always_inline bool +_dl_ppc64_addr_sym_match (const struct link_map *l, const ElfW(Sym) *sym, + const ElfW(Sym) *matchsym, ElfW(Addr) addr) +{ + ElfW(Addr) value = l->l_addr + sym->st_value; + if (_dl_ppc64_is_opd_sym (l, sym)) + { + if (addr < value || addr >= value + 24) + { + value = *(ElfW(Addr) *) value; + if (addr < value || addr >= value + sym->st_size) + return false; + } + } + else if (sym->st_size == 0) + { + if (addr != value) + return false; + } + else if (addr < value || addr >= value + sym->st_size) + return false; + + if (matchsym == NULL) + return true; + + ElfW(Addr) matchvalue = l->l_addr + matchsym->st_value; + if (_dl_ppc64_is_opd_sym (l, matchsym) + && (addr < matchvalue || addr > matchvalue + 24)) + matchvalue = *(ElfW(Addr) *) matchvalue; + + return matchvalue < value; +} + +/* If this is a function symbol defined past the end of our dynamic + section, then it must be a function descriptor. Allow these symbols + to match their associated function code range as well as the + descriptor addresses. */ +#undef DL_ADDR_SYM_MATCH +#define DL_ADDR_SYM_MATCH(L, SYM, MATCHSYM, ADDR) \ + _dl_ppc64_addr_sym_match (L, SYM, MATCHSYM, ADDR) + +#endif /* ldsodefs.h */ |