2003-12-17  Carlos O'Donell  <carlos@baldric.uwo.ca>

	* sysdeps/hppa/fpu/fclrexcpt.c (feclearexcept): Right shift
	FE_ALL_EXCEPT before complimenting.
	* sysdeps/hppa/fpu/fegetenv.c (fegetenv): Use asm 'ma,' completer,
	and gcc '+r' constraint.
	* sysdeps/hppa/fpu/feholdexcpt.c (feholdexcept): Likewise.
	* sysdeps/hppa/fpu/fesetenv.c (fesetenv): Likewise.
	* sysdeps/hppa/fpu/feupdateenv.c (feupdateenv): Read raised
	exception bits, OR with envp, pass to fesetenv.
	* sysdeps/hppa/fpu/fraiseexcpt.c (feraiseexcept): Add delayed
	exception flushing, FE_UNDERFLOW is DBL_MIN/3.0, FE_INEXACT is
	triggered by M_PI/69.69 converted to single precision.
	* sysdeps/hppa/fpu/fsetexcptflg.c (fesetexceptflag): Set enable
	bits not raised exception bits.

	* sysdeps/hppa/Makefile: Add dl-symaddr and dl-fptr to the
	correct build strings.
	* sysdeps/hppa/dl-fptr.h: New file.
	* sysdeps/hppa/dl-fptr.c: Removed.
	* sysdeps/hppa/dl-symaddr.c (_dl_symbol_address): Use _dl_make_ftpr,
	remove const qualifier for map.
	(_dl_function_address): Removed.
	* sysdeps/hppa/dl-lookupcfg.h: DL_LOOKUP_ADDRESS must clear
	PLABEL32 bits, define DL_AUTO_FUNCTION_ADDRESS and
	DL_STATIC_FUNCTION_ADDRESS, DL_DT_INIT_ADDRESS and
	DL_DT_FINI_ADDRESS use the previous two macros.

	* misc/mntent_r.c: Change encoding to match recently changed decoder.
This commit is contained in:
Ulrich Drepper 2003-12-18 04:02:31 +00:00
parent 4ae4facccf
commit 592f26a3ed
12 changed files with 171 additions and 306 deletions

View File

@ -1,3 +1,31 @@
2003-12-17 Carlos O'Donell <carlos@baldric.uwo.ca>
* sysdeps/hppa/fpu/fclrexcpt.c (feclearexcept): Right shift
FE_ALL_EXCEPT before complimenting.
* sysdeps/hppa/fpu/fegetenv.c (fegetenv): Use asm 'ma,' completer,
and gcc '+r' constraint.
* sysdeps/hppa/fpu/feholdexcpt.c (feholdexcept): Likewise.
* sysdeps/hppa/fpu/fesetenv.c (fesetenv): Likewise.
* sysdeps/hppa/fpu/feupdateenv.c (feupdateenv): Read raised
exception bits, OR with envp, pass to fesetenv.
* sysdeps/hppa/fpu/fraiseexcpt.c (feraiseexcept): Add delayed
exception flushing, FE_UNDERFLOW is DBL_MIN/3.0, FE_INEXACT is
triggered by M_PI/69.69 converted to single precision.
* sysdeps/hppa/fpu/fsetexcptflg.c (fesetexceptflag): Set enable
bits not raised exception bits.
* sysdeps/hppa/Makefile: Add dl-symaddr and dl-fptr to the
correct build strings.
* sysdeps/hppa/dl-fptr.h: New file.
* sysdeps/hppa/dl-fptr.c: Removed.
* sysdeps/hppa/dl-symaddr.c (_dl_symbol_address): Use _dl_make_ftpr,
remove const qualifier for map.
(_dl_function_address): Removed.
* sysdeps/hppa/dl-lookupcfg.h: DL_LOOKUP_ADDRESS must clear
PLABEL32 bits, define DL_AUTO_FUNCTION_ADDRESS and
DL_STATIC_FUNCTION_ADDRESS, DL_DT_INIT_ADDRESS and
DL_DT_FINI_ADDRESS use the previous two macros.
2003-12-17 Jakub Jelinek <jakub@redhat.com>
* malloc/mtrace.c (tr_old_memalign_hook): New variable.
@ -9,7 +37,7 @@
2003-12-17 Ulrich Drepper <drepper@redhat.com>
* misc/mntent_r.c: Change encoding to match recently change decoder.
* misc/mntent_r.c: Change encoding to match recently changed decoder.
Patch by Alexander Achenbach <xela@slit.de>.
2003-12-16 Steven Munroe <sjmunroe@us.ibm.com>

View File

@ -1,211 +0,0 @@
/* Make dynamic PLABELs for function pointers. HPPA version.
Copyright (C) 1999, 2000, 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
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. */
#include <unistd.h>
#include <string.h>
#include <sys/param.h>
#include <sys/mman.h>
#include <link.h>
#include <errno.h>
#include <ldsodefs.h>
#include <elf/dynamic-link.h>
#include <dl-machine.h>
#ifdef _LIBC_REENTRANT
# include <pt-machine.h>
/* Remember, we use 0 to mean that a lock is taken on PA-RISC. */
static int __hppa_fptr_lock = 1;
#endif
/* Because ld.so is now versioned, these functions can be in their own
file; no relocations need to be done to call them. Of course, if
ld.so is not versioned... */
#if 0
#ifndef DO_VERSIONING
# error "This will not work with versioning turned off, sorry."
#endif
#endif
#ifdef MAP_ANON
/* The fd is not examined when using MAP_ANON. */
# define ANONFD -1
#else
# define ANONFD GL(dl_zerofd)
#endif
struct hppa_fptr __boot_ldso_fptr[HPPA_BOOT_FPTR_SIZE];
struct hppa_fptr *__fptr_root = NULL;
struct hppa_fptr *__fptr_next = __boot_ldso_fptr;
static struct hppa_fptr *__fptr_free = NULL;
int __fptr_count = HPPA_BOOT_FPTR_SIZE;
Elf32_Addr
__hppa_make_fptr (const struct link_map *sym_map, Elf32_Addr value,
struct hppa_fptr **root, struct hppa_fptr *mem)
{
struct hppa_fptr **loc;
struct hppa_fptr *f;
#ifdef _LIBC_REENTRANT
/* Make sure we are alone. We don't need a lock during bootstrap. */
if (mem == NULL)
while (testandset (&__hppa_fptr_lock));
#endif
/* Search the sorted linked list for an existing entry for this
symbol. */
loc = root;
f = *loc;
while (f != NULL && f->func <= value)
{
if (f->func == value)
goto found;
loc = &f->next;
f = *loc;
}
/* Not found. Create a new one. */
if (mem != NULL)
f = mem;
else if (__fptr_free != NULL)
{
f = __fptr_free;
__fptr_free = f->next;
}
else
{
if (__fptr_count == 0)
{
#ifndef MAP_ANON
# define MAP_ANON 0
if (GL(dl_zerofd) == -1)
{
GL(dl_zerofd) = _dl_sysdep_open_zero_fill ();
if (GL(dl_zerofd) == -1)
{
__close (fd);
_dl_signal_error (errno, NULL, NULL,
"cannot open zero fill device");
}
}
#endif
__fptr_next = __mmap (0, GL(dl_pagesize), PROT_READ | PROT_WRITE,
MAP_ANON | MAP_PRIVATE, ANONFD, 0);
if (__fptr_next == MAP_FAILED)
_dl_signal_error(errno, NULL, NULL, "cannot map page for fptr");
__fptr_count = GL(dl_pagesize) / sizeof (struct hppa_fptr);
}
f = __fptr_next++;
__fptr_count--;
}
f->func = value;
/* GOT has already been relocated in elf_get_dynamic_info - don't
try to relocate it again. */
f->gp = sym_map->l_info[DT_PLTGOT]->d_un.d_ptr;
f->next = *loc;
*loc = f;
found:
#ifdef _LIBC_REENTRANT
/* Release the lock. Again, remember, zero means the lock is taken! */
if (mem == NULL)
__hppa_fptr_lock = 1;
#endif
/* Set bit 30 to indicate to $$dyncall that this is a PLABEL. */
return (Elf32_Addr) f | 2;
}
void
_dl_unmap (struct link_map *map)
{
struct hppa_fptr **floc;
struct hppa_fptr *f;
struct hppa_fptr **lloc;
struct hppa_fptr *l;
__munmap ((void *) map->l_map_start, map->l_map_end - map->l_map_start);
#ifdef _LIBC_REENTRANT
/* Make sure we are alone. */
while (testandset (&__hppa_fptr_lock));
#endif
/* Search the sorted linked list for the first entry for this object. */
floc = &__fptr_root;
f = *floc;
while (f != NULL && f->func < map->l_map_start)
{
floc = &f->next;
f = *floc;
}
/* We found one. */
if (f != NULL && f->func < map->l_map_end)
{
/* Get the last entry. */
lloc = floc;
l = f;
while (l && l->func < map->l_map_end)
{
lloc = &l->next;
l = *lloc;
}
/* Updated FPTR. */
*floc = l;
/* Prepend them to the free list. */
*lloc = __fptr_free;
__fptr_free = f;
}
#ifdef _LIBC_REENTRANT
/* Release the lock. */
__hppa_fptr_lock = 1;
#endif
}
Elf32_Addr
_dl_lookup_address (const void *address)
{
Elf32_Addr addr = (Elf32_Addr) address;
struct hppa_fptr *f;
#ifdef _LIBC_REENTRANT
/* Make sure we are alone. */
while (testandset (&__hppa_fptr_lock));
#endif
for (f = __fptr_root; f != NULL; f = f->next)
if (f == address)
{
addr = f->func;
break;
}
#ifdef _LIBC_REENTRANT
/* Release the lock. */
__hppa_fptr_lock = 1;
#endif
return addr;
}

35
sysdeps/hppa/dl-fptr.h Normal file
View File

@ -0,0 +1,35 @@
/* Function descriptors. HPPA version.
Copyright (C) 2003 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 dl_hppa_fptr_h
#define dl_hppa_fptr_h 1
#include <sysdeps/generic/dl-fptr.h>
/* There are currently 20 dynamic symbols in ld.so.
ELF_MACHINE_BOOT_FPTR_TABLE_LEN needs to be at least that big. */
#define ELF_MACHINE_BOOT_FPTR_TABLE_LEN 200
#define ELF_MACHINE_LOAD_ADDRESS(var, symbol) \
asm (" addil LT%%" #symbol ", %%r19\n" \
" ldw RT%%" #symbol "(%%sr0,%%r1), %0\n" \
: "=&r" (var));
#endif /* !dl_hppa_fptr_h */

View File

@ -26,27 +26,44 @@
/* Forward declaration. */
struct link_map;
void *_dl_symbol_address (const struct link_map *map, const ElfW(Sym) *ref);
void *_dl_symbol_address (struct link_map *map, const ElfW(Sym) *ref);
#define DL_SYMBOL_ADDRESS(map, ref) _dl_symbol_address(map, ref)
Elf32_Addr _dl_lookup_address (const void *address);
#define DL_LOOKUP_ADDRESS(addr) _dl_lookup_address (addr)
/* Clear the bottom two bits so generic code can find the fdesc entry */
#define DL_LOOKUP_ADDRESS(addr) \
(_dl_lookup_address ((void *)((unsigned long)addr & ~3)))
void _dl_unmap (struct link_map *map);
#define DL_UNMAP(map) _dl_unmap (map)
extern Elf32_Addr _dl_function_address (const struct link_map *map,
Elf32_Addr start);
#define DL_AUTO_FUNCTION_ADDRESS(map, addr) \
({ \
unsigned int fptr[2]; \
fptr[0] = (unsigned int) (addr); \
fptr[1] = (map)->l_info[DT_PLTGOT]->d_un.d_ptr; \
/* Set bit 30 to indicate to $$dyncall that this is a PLABEL. */ \
(ElfW(Addr))((unsigned int)fptr | 2); \
})
#define DL_STATIC_FUNCTION_ADDRESS(map, addr) \
({ \
static unsigned int fptr[2]; \
fptr[0] = (unsigned int) (addr); \
fptr[1] = (map)->l_info[DT_PLTGOT]->d_un.d_ptr; \
/* Set bit 30 to indicate to $$dyncall that this is a PLABEL. */ \
(ElfW(Addr))((unsigned int)fptr | 2); \
})
#define DL_FUNCTION_ADDRESS(map, addr) _dl_function_address (map, addr)
/* The test for "addr & 2" below is to accomodate old binaries which
violated the ELF ABI by pointing DT_INIT and DT_FINI at a function
pointer. */
descriptor. */
#define DL_DT_INIT_ADDRESS(map, addr) \
((Elf32_Addr)(addr) & 2 ? (addr) : DL_FUNCTION_ADDRESS (map, addr))
((Elf32_Addr)(addr) & 2 ? (addr) : DL_AUTO_FUNCTION_ADDRESS (map, addr))
#define DL_DT_FINI_ADDRESS(map, addr) \
((Elf32_Addr)(addr) & 2 ? (addr) : DL_FUNCTION_ADDRESS (map, addr))
((Elf32_Addr)(addr) & 2 ? (addr) : DL_AUTO_FUNCTION_ADDRESS (map, addr))

View File

@ -21,19 +21,16 @@
#include <dl-machine.h>
void *
_dl_symbol_address (const struct link_map *map, const ElfW(Sym) *ref)
_dl_symbol_address (struct link_map *map, const ElfW(Sym) *ref)
{
/* Find the "ip" from the "map" and symbol "ref" */
Elf32_Addr value = (map ? map->l_addr : 0) + ref->st_value;
/* On hppa, we have to return the pointer to function descriptor. */
if (ELFW(ST_TYPE) (ref->st_info) == STT_FUNC)
return (void *) __hppa_make_fptr (map, value, &__fptr_root, NULL);
/* On hppa, we have to return the pointer to function descriptor.
This involves an "| 2" to inform $$dyncall that this is a plabel32 */
if (ELFW(ST_TYPE) (ref->st_info) == STT_FUNC){
return (void *)((unsigned long)_dl_make_fptr (map, ref, value) | 2);
}
else
return (void *) value;
}
ElfW(Addr)
_dl_function_address (const struct link_map *map, ElfW(Addr) start)
{
return __hppa_make_fptr (map, start, &__fptr_root, NULL);
}

View File

@ -29,7 +29,7 @@ feclearexcept (int excepts)
__asm__ ("fstd %%fr0,0(%1)" : "=m" (*sw) : "r" (sw));
/* Clear all the relevant bits. */
sw[0] &= ~(excepts & FE_ALL_EXCEPT) << 27;
sw[0] &= ~((excepts & FE_ALL_EXCEPT) << 27);
__asm__ ("fldd 0(%0),%%fr0" : : "r" (sw));
/* Success. */

View File

@ -24,10 +24,10 @@ int
fegetenv (fenv_t *envp)
{
__asm__ (
"fstd %%fr0,0(%2)\n"
"fstd,ma %%fr1,8(%2)\n"
"fstd,ma %%fr2,8(%2)\n"
"fstd %%fr3,0(%2)\n"
: "=m" (*envp), "=r" (envp) : "1" (envp));
"fstd,ma %%fr0,8(%1)\n"
"fstd,ma %%fr1,8(%1)\n"
"fstd,ma %%fr2,8(%1)\n"
"fstd %%fr3,0(%1)\n"
: "=m" (*envp), "+r" (envp));
return 0;
}

View File

@ -25,18 +25,16 @@ int
feholdexcept (fenv_t *envp)
{
fenv_t clear;
fenv_t * _regs = envp;
/* Store the environment. */
{
fenv_t * _regs = envp;
__asm__ (
"fstd %%fr0,0(%2)\n"
"fstd,ma %%fr1,8(%2)\n"
"fstd,ma %%fr2,8(%2)\n"
"fstd %%fr3,0(%2)\n"
: "=m" (*_regs), "=r" (_regs) : "1" (_regs));
"fstd,ma %%fr0,8(%1)\n"
"fstd,ma %%fr1,8(%1)\n"
"fstd,ma %%fr2,8(%1)\n"
"fstd %%fr3,0(%1)\n"
: "=m" (*_regs), "+r" (_regs));
memcpy (&clear, envp, sizeof (clear));
}
/* Now clear all exceptions. */
clear.__status_word &= ~(FE_ALL_EXCEPT << 27);
@ -46,15 +44,13 @@ feholdexcept (fenv_t *envp)
clear.__status_word &= ~FE_ALL_EXCEPT;
/* Load the new environment. */
{
fenv_t * _regs = &clear + 1;
_regs = &clear;
__asm__ (
"fldd,mb -8(%2),%%fr3\n"
"fldd,mb -8(%2),%%fr2\n"
"fldd,mb -8(%2),%%fr1\n"
"fldd -8(%2),%%fr0\n"
: "=m" (*_regs), "=r" (_regs) : "1" (_regs));
}
"fldd,ma -8(%1),%%fr3\n"
"fldd,ma -8(%1),%%fr2\n"
"fldd,ma -8(%1),%%fr1\n"
"fldd 0(%1),%%fr0\n"
: "=m" (*_regs), "+r" (_regs));
return 0;
}

View File

@ -26,20 +26,18 @@ int
fesetenv (const fenv_t *envp)
{
fenv_t temp;
fenv_t * _regs = &temp;
/* Install the environment specified by ENVP. But there are a few
values which we do not want to come from the saved environment.
Therefore, we get the current environment and replace the values
we want to use from the environment specified by the parameter. */
{
fenv_t * _regs = &temp;
__asm__ (
"fstd %%fr0,0(%2)\n"
"fstd,ma %%fr1,8(%2)\n"
"fstd,ma %%fr2,8(%2)\n"
"fstd %%fr3,0(%2)\n"
: "=m" (*_regs), "=r" (_regs) : "1" (_regs));
}
"fstd,ma %%fr0,8(%1)\n"
"fstd,ma %%fr1,8(%1)\n"
"fstd,ma %%fr2,8(%1)\n"
"fstd %%fr3,0(%1)\n"
: "=m" (*_regs), "+r" (_regs));
temp.__status_word &= ~(FE_ALL_EXCEPT
| (FE_ALL_EXCEPT << 27)
@ -55,15 +53,12 @@ fesetenv (const fenv_t *envp)
| (FE_ALL_EXCEPT << 27)));
/* Load the new environment. */
{
fenv_t * _regs = &temp + 1;
__asm__ (
"fldd,mb -8(%2),%%fr3\n"
"fldd,mb -8(%2),%%fr2\n"
"fldd,mb -8(%2),%%fr1\n"
"fldd -8(%2),%%fr0\n"
: "=m" (*_regs), "=r" (_regs) : "1" (_regs));
}
"fldd,ma -8(%1),%%fr3\n"
"fldd,ma -8(%1),%%fr2\n"
"fldd,ma -8(%1),%%fr1\n"
"fldd 0(%1),%%fr0\n"
: "=m" (*_regs), "+r" (_regs));
/* Success. */
return 0;

View File

@ -27,14 +27,12 @@ feupdateenv (const fenv_t *envp)
/* Get the current exception status. */
__asm__ ("fstd %%fr0,0(%1)" : "=m" (*sw) : "r" (sw));
sw[0] &= (FE_ALL_EXCEPT << 27);
sw[0] &= FE_ALL_EXCEPT;
envp->__status_word = envp->__status_word | sw[0];
/* Install new environment. */
fesetenv (envp);
/* Raise the saved exception. */
feraiseexcept (sw[0] >> 27);
/* Success. */
return 0;
}

View File

@ -22,6 +22,9 @@
#include <float.h>
#include <math.h>
/* Please see section 10,
page 10-5 "Delayed Trapping" in the PA-RISC 2.0 Architecture manual */
int
feraiseexcept (int excepts)
{
@ -35,54 +38,62 @@ feraiseexcept (int excepts)
away something important, and so we can force delayed traps to
occur. */
/* FIXME: These all need verification! */
/* We use "fldd 0(%%sr0,%%sp),%0" to flush the delayed exception */
/* First: invalid exception. */
/* First: Invalid exception. */
if (excepts & FE_INVALID)
{
/* One example of a invalid operation is 0 * Infinity. */
double d = HUGE_VAL;
__asm__ __volatile__ ("fmpy,dbl %1,%%fr0,%0\n\t"
/* FIXME: is this a proper trap barrier? */
"fcpy,dbl %%fr0,%%fr0" : "=f" (d) : "0" (d));
__asm__ __volatile__ (
" fcpy,dbl %%fr0,%%fr22\n"
" fmpy,dbl %0,%%fr22,%0\n"
" fldd 0(%%sr0,%%sp),%0"
: "+f" (d) : : "%fr22" );
}
/* Next: division by zero. */
/* Second: Division by zero. */
if (excepts & FE_DIVBYZERO)
{
double d = 1.0;
__asm__ __volatile__ ("fdiv,dbl %1,%%fr0,%0\n\t"
"fcpy,dbl %%fr0,%%fr0" : "=f" (d) : "0" (d));
__asm__ __volatile__ (
" fcpy,dbl %%fr0,%%fr22\n"
" fdiv,dbl %0,%%fr22,%0\n"
" fldd 0(%%sr0,%%sp),%0"
: "+f" (d) : : "%fr22" );
}
/* Next: overflow. */
/* FIXME: Compare with IA-64 - do we have the same problem? */
/* Third: Overflow. */
if (excepts & FE_OVERFLOW)
{
double d = DBL_MAX;
__asm__ __volatile__ ("fmpy,dbl %1,%1,%0\n\t"
"fcpy,dbl %%fr0,%%fr0" : "=f" (d) : "0" (d));
__asm__ __volatile__ (
" fadd,dbl %0,%0,%0\n"
" fldd 0(%%sr0,%%sp),%0"
: "+f" (d) );
}
/* Next: underflow. */
/* Fourth: Underflow. */
if (excepts & FE_UNDERFLOW)
{
double d = DBL_MIN;
double e = 69.69;
__asm__ __volatile__ ("fdiv,dbl %1,%2,%0\n\t"
"fcpy,dbl %%fr0,%%fr0" : "=f" (d) : "0" (d), "f" (e));
double e = 3.0;
__asm__ __volatile__ (
" fdiv,dbl %0,%1,%0\n"
" fldd 0(%%sr0,%%sp),%0"
: "+f" (d) : "f" (e) );
}
/* Last: inexact. */
/* Fifth: Inexact */
if (excepts & FE_INEXACT)
{
double d = 1.0;
double e = M_PI;
__asm__ __volatile__ ("fdiv,dbl %1,%2,%0\n\t"
"fcpy,dbl %%fr0,%%fr0" : "=f" (d) : "0" (d), "f" (e));
double d = M_PI;
double e = 69.69;
__asm__ __volatile__ (
" fdiv,dbl %0,%1,%%fr22\n"
" fcnvfxt,dbl,sgl %%fr22,%%fr22L\n"
" fldd 0(%%sr0,%%sp),%%fr22"
: : "f" (d), "f" (e) : "%fr22" );
}
/* Success. */

View File

@ -29,8 +29,7 @@ fesetexceptflag (const fexcept_t *flagp, int excepts)
/* Get the current status word. */
__asm__ ("fstd %%fr0,0(%1)" : "=m" (*sw) : "r" (sw));
/* Install the new exception flags bits. */
sw[0] &= ~(excepts & (FE_ALL_EXCEPT >> 27));
/* Install new enable trap bits */
sw[0] |= (*flagp & excepts & FE_ALL_EXCEPT) << 27;
/* Store the new status word. */