diff options
Diffstat (limited to 'sysdeps')
56 files changed, 1414 insertions, 620 deletions
diff --git a/sysdeps/generic/dl-sysdep.c b/sysdeps/generic/dl-sysdep.c index 34498a880c..1fae16efce 100644 --- a/sysdeps/generic/dl-sysdep.c +++ b/sysdeps/generic/dl-sysdep.c @@ -1,5 +1,5 @@ /* Operating system support for run-time dynamic linker. Generic Unix version. - Copyright (C) 1995-1998, 2000-2003, 2004 Free Software Foundation, Inc. + Copyright (C) 1995-1998, 2000-2003, 2004, 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 @@ -39,6 +39,12 @@ #include <hp-timing.h> #include <tls.h> +#ifdef _DL_FIRST_PLATFORM +# define _DL_FIRST_EXTRA (_DL_FIRST_PLATFORM + _DL_PLATFORMS_COUNT) +#else +# define _DL_FIRST_EXTRA _DL_HWCAP_COUNT +#endif + extern char **_environ attribute_hidden; extern void _end attribute_hidden; @@ -149,7 +155,7 @@ _dl_sysdep_start (void **start_argptr, GLRO(dl_platform) = av->a_un.a_ptr; break; case AT_HWCAP: - GLRO(dl_hwcap) = av->a_un.a_val; + GLRO(dl_hwcap) = (unsigned long int) av->a_un.a_val; break; case AT_CLKTCK: GLRO(dl_clktck) = av->a_un.a_val; @@ -172,10 +178,6 @@ _dl_sysdep_start (void **start_argptr, #endif } -#ifdef DL_SYSDEP_OSCHECK - DL_SYSDEP_OSCHECK (dl_fatal); -#endif - #ifndef HAVE_AUX_SECURE if (seen != -1) { @@ -343,7 +345,7 @@ _dl_important_hwcaps (const char *platform, size_t platform_len, size_t *sz, size_t *max_capstrlen) { /* Determine how many important bits are set. */ - unsigned long int masked = GLRO(dl_hwcap) & GLRO(dl_hwcap_mask); + uint64_t masked = GLRO(dl_hwcap) & GLRO(dl_hwcap_mask); size_t cnt = platform != NULL; size_t n, m; size_t total; @@ -353,18 +355,64 @@ _dl_important_hwcaps (const char *platform, size_t platform_len, size_t *sz, char *cp; /* Count the number of bits set in the masked value. */ - for (n = 0; (~((1UL << n) - 1) & masked) != 0; ++n) - if ((masked & (1UL << n)) != 0) + for (n = 0; (~((1ULL << n) - 1) & masked) != 0; ++n) + if ((masked & (1ULL << n)) != 0) ++cnt; +#if (defined NEED_DL_SYSINFO || defined NEED_DL_SYSINFO_DSO) && defined SHARED + /* The system-supplied DSO can contain a note of type 2, vendor "GNU". + This gives us a list of names to treat as fake hwcap bits. */ + + const char *dsocaps = NULL; + size_t dsocapslen = 0; + if (GLRO(dl_sysinfo_map) != NULL) + { + const ElfW(Phdr) *const phdr = GLRO(dl_sysinfo_map)->l_phdr; + const ElfW(Word) phnum = GLRO(dl_sysinfo_map)->l_phnum; + for (uint_fast16_t i = 0; i < phnum; ++i) + if (phdr[i].p_type == PT_NOTE) + { + const ElfW(Addr) start = (phdr[i].p_vaddr + + GLRO(dl_sysinfo_map)->l_addr); + const struct + { + ElfW(Word) vendorlen; + ElfW(Word) datalen; + ElfW(Word) type; + } *note = (const void *) start; + while ((ElfW(Addr)) (note + 1) - start < phdr[i].p_memsz) + { +#define ROUND(len) (((len) + sizeof (ElfW(Word)) - 1) & -sizeof (ElfW(Word))) + if (note->type == 2 + && note->vendorlen == sizeof "GNU" + && !memcmp ((note + 1), "GNU", sizeof "GNU") + && note->datalen > 2 * sizeof (ElfW(Word)) + 2) + { + const ElfW(Word) *p = ((const void *) (note + 1) + + ROUND (sizeof "GNU")); + cnt += *p++; + ++p; /* Skip mask word. */ + dsocaps = (const char *) p; + dsocapslen = note->datalen - sizeof *p; + break; + } + note = ((const void *) (note + 1) + + ROUND (note->vendorlen) + ROUND (note->datalen)); + } + if (dsocaps != NULL) + break; + } + } +#endif + #ifdef USE_TLS /* For TLS enabled builds always add 'tls'. */ ++cnt; #else if (cnt == 0) { - /* If we have platform name and no important capability we only have - the base directory to search. */ + /* If we no have platform name and no important capability we only + have the base directory to search. */ result = (struct r_strlenpair *) malloc (sizeof (*result)); if (result == NULL) goto no_memory; @@ -380,12 +428,26 @@ _dl_important_hwcaps (const char *platform, size_t platform_len, size_t *sz, /* Create temporary data structure to generate result table. */ temp = (struct r_strlenpair *) alloca (cnt * sizeof (*temp)); m = 0; +#if defined NEED_DL_SYSINFO || defined NEED_DL_SYSINFO_DSO + if (dsocaps != NULL) + { + GLRO(dl_hwcap) |= ((uint64_t) ((const ElfW(Word) *) dsocaps)[-1] + << _DL_FIRST_EXTRA); + for (const char *p = dsocaps; + p < dsocaps + dsocapslen; + p += temp[m++].len + 1) + { + temp[m].str = p; + temp[m].len = strlen (p); + } + } +#endif for (n = 0; masked != 0; ++n) - if ((masked & (1UL << n)) != 0) + if ((masked & (1ULL << n)) != 0) { temp[m].str = _dl_hwcap_string (n); temp[m].len = strlen (temp[m].str); - masked ^= 1UL << n; + masked ^= 1ULL << n; ++m; } if (platform != NULL) @@ -503,8 +565,8 @@ _dl_important_hwcaps (const char *platform, size_t platform_len, size_t *sz, ++rp; } - /* The second have starts right after the first part of the string of - corresponding entry in the first half. */ + /* The second half starts right after the first part of the string of + the corresponding entry in the first half. */ do { rp[0].str = rp[-(1 << (cnt - 1))].str + temp[cnt - 1].len + 1; diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h index e1a934aeda..2e3254356b 100644 --- a/sysdeps/generic/ldsodefs.h +++ b/sysdeps/generic/ldsodefs.h @@ -199,6 +199,10 @@ struct La_mips_32_regs; struct La_mips_32_retval; struct La_mips_64_regs; struct La_mips_64_retval; +struct La_sparc32_regs; +struct La_sparc32_retval; +struct La_sparc64_regs; +struct La_sparc64_retval; struct audit_ifaces { @@ -270,6 +274,16 @@ struct audit_ifaces const struct La_mips_64_regs *, unsigned int *, const char *name, long int *framesizep); + Elf32_Addr (*sparc32_gnu_pltenter) (Elf32_Sym *, unsigned int, + uintptr_t *, uintptr_t *, + const struct La_sparc32_regs *, + unsigned int *, const char *name, + long int *framesizep); + Elf64_Addr (*sparc64_gnu_pltenter) (Elf64_Sym *, unsigned int, + uintptr_t *, uintptr_t *, + const struct La_sparc64_regs *, + unsigned int *, const char *name, + long int *framesizep); }; union { @@ -328,6 +342,16 @@ struct audit_ifaces const struct La_mips_64_regs *, struct La_mips_64_retval *, const char *); + unsigned int (*sparc32_gnu_pltexit) (Elf32_Sym *, unsigned int, + uintptr_t *, uintptr_t *, + const struct La_sparc32_regs *, + struct La_sparc32_retval *, + const char *); + unsigned int (*sparc64_gnu_pltexit) (Elf64_Sym *, unsigned int, + uintptr_t *, uintptr_t *, + const struct La_sparc32_regs *, + struct La_sparc32_retval *, + const char *); }; unsigned int (*objclose) (uintptr_t *); @@ -587,10 +611,10 @@ struct rtld_global_ro EXTERN int _dl_correct_cache_id; /* Mask for hardware capabilities that are available. */ - EXTERN unsigned long int _dl_hwcap; + EXTERN uint64_t _dl_hwcap; /* Mask for important hardware capabilities we honour. */ - EXTERN unsigned long int _dl_hwcap_mask; + EXTERN uint64_t _dl_hwcap_mask; /* Get architecture specific definitions. */ #define PROCINFO_DECL @@ -636,6 +660,10 @@ struct rtld_global_ro /* The vsyscall page is a virtual DSO pre-mapped by the kernel. This points to its ELF header. */ EXTERN const ElfW(Ehdr) *_dl_sysinfo_dso; + + /* At startup time we set up the normal DSO data structure for it, + and this points to it. */ + EXTERN struct link_map *_dl_sysinfo_map; #endif #ifdef SHARED diff --git a/sysdeps/ia64/fpu/e_acosh.S b/sysdeps/ia64/fpu/e_acosh.S index b55a6ab43c..fb25fa0053 100644 --- a/sysdeps/ia64/fpu/e_acosh.S +++ b/sysdeps/ia64/fpu/e_acosh.S @@ -1,7 +1,7 @@ .file "acosh.s" -// Copyright (c) 2000 - 2003, Intel Corporation +// Copyright (c) 2000 - 2005, Intel Corporation // All rights reserved. // // Contributed 2000 by the Intel Numerics Group, Intel Corporation @@ -45,6 +45,7 @@ // 05/20/02 Cleaned up namespace and sf0 syntax // 02/06/03 Reordered header: .section, .global, .proc, .align // 05/14/03 Improved performance, set denormal flag for unorms >= 1.0 +// 03/31/05 Reformatted delimiters between data tables // // API // ============================================================== diff --git a/sysdeps/ia64/fpu/e_acoshl.S b/sysdeps/ia64/fpu/e_acoshl.S index 5eb2b3466b..42e1f394ef 100644 --- a/sysdeps/ia64/fpu/e_acoshl.S +++ b/sysdeps/ia64/fpu/e_acoshl.S @@ -1,7 +1,7 @@ .file "acoshl.s" -// Copyright (c) 2000 - 2003, Intel Corporation +// Copyright (c) 2000 - 2005, Intel Corporation // All rights reserved. // // Contributed 2000 by the Intel Numerics Group, Intel Corporation @@ -47,6 +47,7 @@ // 05/20/02 Cleaned up namespace and sf0 syntax // 08/14/02 Changed mli templates to mlx // 02/06/03 Reorganized data tables +// 03/31/05 Reformatted delimiters between data tables // //********************************************************************* // @@ -258,6 +259,7 @@ data8 0x9E34AF4D372861E0, 0x3FFB // .77248925727776366270605984806795850504e-1 data8 0xF3DC502AEE14C4AE, 0x3FA6 // .3077953476682583606615438814166025592e-26 LOCAL_OBJECT_END(Poly_P) +// LOCAL_OBJECT_START(Poly_Q) data8 0xF76E3FD3C7680357, 0x3FF1 // .11798413344703621030038719253730708525e-3 data8 0xD107D2E7273263AE, 0x3FF7 // .63791065024872525660782716786703188820e-2 diff --git a/sysdeps/ia64/fpu/e_atanh.S b/sysdeps/ia64/fpu/e_atanh.S index 5ae96dc90b..4ae5ee6926 100644 --- a/sysdeps/ia64/fpu/e_atanh.S +++ b/sysdeps/ia64/fpu/e_atanh.S @@ -1,7 +1,7 @@ .file "atanh.s" -// Copyright (c) 2000 - 2003, Intel Corporation +// Copyright (c) 2000 - 2005, Intel Corporation // All rights reserved. // // Contributed 2000 by the Intel Numerics Group, Intel Corporation @@ -44,6 +44,7 @@ // 05/20/02 Cleaned up namespace and sf0 syntax // 02/06/03 Reordered header: .section, .global, .proc, .align // 05/26/03 Improved performance, fixed to handle unorms +// 03/31/05 Reformatted delimiters between data tables // // API // ============================================================== diff --git a/sysdeps/ia64/fpu/e_cosh.S b/sysdeps/ia64/fpu/e_cosh.S index 38bd80e146..885456b389 100644 --- a/sysdeps/ia64/fpu/e_cosh.S +++ b/sysdeps/ia64/fpu/e_cosh.S @@ -1,7 +1,7 @@ .file "cosh.s" -// Copyright (c) 2000 - 2002, Intel Corporation +// Copyright (c) 2000 - 2005, Intel Corporation // All rights reserved. // // Contributed 2000 by the Intel Numerics Group, Intel Corporation @@ -46,6 +46,7 @@ // 05/07/01 Reworked to improve speed of all paths // 05/20/02 Cleaned up namespace and sf0 syntax // 11/15/02 Improved speed with new algorithm +// 03/31/05 Reformatted delimiters between data tables // API //============================================================== diff --git a/sysdeps/ia64/fpu/e_coshf.S b/sysdeps/ia64/fpu/e_coshf.S index 6d30064256..97cb4e1771 100644 --- a/sysdeps/ia64/fpu/e_coshf.S +++ b/sysdeps/ia64/fpu/e_coshf.S @@ -1,7 +1,7 @@ .file "coshf.s" -// Copyright (c) 2000 - 2002, Intel Corporation +// Copyright (c) 2000 - 2005, Intel Corporation // All rights reserved. // // Contributed 2000 by the Intel Numerics Group, Intel Corporation @@ -47,6 +47,7 @@ // 05/07/01 Reworked to improve speed of all paths // 05/20/02 Cleaned up namespace and sf0 syntax // 11/15/02 Improved algorithm based on expf +// 03/31/05 Reformatted delimiters between data tables // // API //********************************************************************* diff --git a/sysdeps/ia64/fpu/e_exp.S b/sysdeps/ia64/fpu/e_exp.S index d22fd18b77..fcc247fb1a 100644 --- a/sysdeps/ia64/fpu/e_exp.S +++ b/sysdeps/ia64/fpu/e_exp.S @@ -1,7 +1,7 @@ .file "exp.s" -// Copyright (c) 2000 - 2003, Intel Corporation +// Copyright (c) 2000 - 2005, Intel Corporation // All rights reserved. // // Contributed 2000 by the Intel Numerics Group, Intel Corporation @@ -53,6 +53,7 @@ // 09/07/02 Force inexact flag // 11/15/02 Split underflow path into zero/nonzero; eliminated fma in main path // 05/30/03 Set inexact flag on unmasked overflow/underflow +// 03/31/05 Reformatted delimiters between data tables // API //============================================================== diff --git a/sysdeps/ia64/fpu/e_exp10.S b/sysdeps/ia64/fpu/e_exp10.S index 6bfc21879d..eafa59dd7c 100644 --- a/sysdeps/ia64/fpu/e_exp10.S +++ b/sysdeps/ia64/fpu/e_exp10.S @@ -1,7 +1,7 @@ .file "exp10.s" -// Copyright (c) 2000 - 2004, Intel Corporation +// Copyright (c) 2000 - 2005, Intel Corporation // All rights reserved. // // Contributed 2000 by the Intel Numerics Group, Intel Corporation @@ -44,6 +44,7 @@ // 09/06/02 Improved performance; no inexact flags on exact cases // 01/29/03 Added missing } to bundle templates // 12/16/04 Call error handling on underflow. +// 03/31/05 Reformatted delimiters between data tables // // API //============================================================== @@ -203,7 +204,6 @@ data8 0x8245cd9ab2cec048, 0x825c62a423d13f0c data8 0x8272fb97b2a5894c, 0x828998760d01faf3 data8 0x82a0393fe0bb0ca8, 0x82b6ddf5dbc35906 // -// // 2^{0.b1 b2 b3 b4 b5} data8 0x8000000000000000, 0x82cd8698ac2ba1d7 data8 0x85aac367cc487b14, 0x88980e8092da8527 diff --git a/sysdeps/ia64/fpu/e_exp10f.S b/sysdeps/ia64/fpu/e_exp10f.S index 46615e98ff..fa54e9039f 100644 --- a/sysdeps/ia64/fpu/e_exp10f.S +++ b/sysdeps/ia64/fpu/e_exp10f.S @@ -1,7 +1,7 @@ .file "exp10f.s" -// Copyright (c) 2000 - 2004, Intel Corporation +// Copyright (c) 2000 - 2005, Intel Corporation // All rights reserved. // // Contributed 2000 by the Intel Numerics Group, Intel Corporation @@ -44,6 +44,7 @@ // 09/06/02 Improved performance and accuracy; no inexact flags on exact cases // 01/29/03 Added missing } to bundle templates // 12/16/04 Call error handling on underflow. +// 03/31/05 Reformatted delimiters between data tables // // API //============================================================== @@ -193,7 +194,6 @@ data8 0x8245cd9ab2cec048, 0x825c62a423d13f0c data8 0x8272fb97b2a5894c, 0x828998760d01faf3 data8 0x82a0393fe0bb0ca8, 0x82b6ddf5dbc35906 // -// // 2^{0.b1 b2 b3 b4 b5} data8 0x8000000000000000, 0x82cd8698ac2ba1d7 data8 0x85aac367cc487b14, 0x88980e8092da8527 diff --git a/sysdeps/ia64/fpu/e_exp2.S b/sysdeps/ia64/fpu/e_exp2.S index 46fca2d3cd..54f652e384 100644 --- a/sysdeps/ia64/fpu/e_exp2.S +++ b/sysdeps/ia64/fpu/e_exp2.S @@ -1,7 +1,7 @@ .file "exp2.s" -// Copyright (c) 2000 - 2003, Intel Corporation +// Copyright (c) 2000 - 2005, Intel Corporation // All rights reserved. // // Contributed 2000 by the Intel Numerics Group, Intel Corporation @@ -43,6 +43,7 @@ // 05/20/02 Cleaned up namespace and sf0 syntax // 09/05/02 Improved performance // 01/17/03 Fixed to call error support when x=1024.0 +// 03/31/05 Reformatted delimiters between data tables // // API //============================================================== @@ -204,7 +205,6 @@ data8 0x8245cd9ab2cec048, 0x825c62a423d13f0c data8 0x8272fb97b2a5894c, 0x828998760d01faf3 data8 0x82a0393fe0bb0ca8, 0x82b6ddf5dbc35906 // -// // 2^{0.b1 b2 b3 b4 b5} data8 0x8000000000000000, 0x82cd8698ac2ba1d7 data8 0x85aac367cc487b14, 0x88980e8092da8527 diff --git a/sysdeps/ia64/fpu/e_exp2f.S b/sysdeps/ia64/fpu/e_exp2f.S index 8ee600c554..36354ae3bd 100644 --- a/sysdeps/ia64/fpu/e_exp2f.S +++ b/sysdeps/ia64/fpu/e_exp2f.S @@ -1,7 +1,7 @@ .file "exp2f.s" -// Copyright (c) 2000 - 2003, Intel Corporation +// Copyright (c) 2000 - 2005, Intel Corporation // All rights reserved. // // Contributed 2000 by the Intel Numerics Group, Intel Corporation @@ -43,6 +43,7 @@ // 05/20/02 Cleaned up namespace and sf0 syntax // 09/05/02 Improved performance and accuracy // 01/17/03 Fixed to call error support when x=128.0 +// 03/31/05 Reformatted delimiters between data tables // // API //============================================================== @@ -198,7 +199,6 @@ data8 0x8245cd9ab2cec048, 0x825c62a423d13f0c data8 0x8272fb97b2a5894c, 0x828998760d01faf3 data8 0x82a0393fe0bb0ca8, 0x82b6ddf5dbc35906 // -// // 2^{0.b1 b2 b3 b4 b5} data8 0x8000000000000000, 0x82cd8698ac2ba1d7 data8 0x85aac367cc487b14, 0x88980e8092da8527 diff --git a/sysdeps/ia64/fpu/e_expf.S b/sysdeps/ia64/fpu/e_expf.S index 3dc0ba9bf6..6fe0a833e2 100644 --- a/sysdeps/ia64/fpu/e_expf.S +++ b/sysdeps/ia64/fpu/e_expf.S @@ -1,7 +1,7 @@ .file "expf.s" -// Copyright (c) 2000 - 2003, Intel Corporation +// Copyright (c) 2000 - 2005, Intel Corporation // All rights reserved. // // Contributed 2000 by the Intel Numerics Group, Intel Corporation @@ -53,6 +53,7 @@ // corrected // 11/15/02 Improved performance on Itanium 2, added possible over/under paths // 05/30/03 Set inexact flag on unmasked overflow/underflow +// 03/31/05 Reformatted delimiters between data tables // // // API diff --git a/sysdeps/ia64/fpu/e_log.S b/sysdeps/ia64/fpu/e_log.S index 7b277f8a40..c644c6f8f7 100644 --- a/sysdeps/ia64/fpu/e_log.S +++ b/sysdeps/ia64/fpu/e_log.S @@ -1,7 +1,7 @@ .file "log.s" -// Copyright (c) 2000 - 2002, Intel Corporation +// Copyright (c) 2000 - 2005, Intel Corporation // All rights reserved. // // Contributed 2000 by the Intel Numerics Group, Intel Corporation @@ -51,6 +51,7 @@ // 05/23/02 Modified algorithm. Now only one polynomial is used // for |x-1| >= 1/256 and for |x-1| < 1/256 // 12/11/02 Improved performance for Itanium 2 +// 03/31/05 Reformatted delimiters between data tables // // API //============================================================== diff --git a/sysdeps/ia64/fpu/e_logf.S b/sysdeps/ia64/fpu/e_logf.S index 186edab501..3d11a296cc 100644 --- a/sysdeps/ia64/fpu/e_logf.S +++ b/sysdeps/ia64/fpu/e_logf.S @@ -1,7 +1,7 @@ .file "logf.s" -// Copyright (c) 2000 - 2003, Intel Corporation +// Copyright (c) 2000 - 2005, Intel Corporation // All rights reserved. // // Contributed 2000 by the Intel Numerics Group, Intel Corporation @@ -47,6 +47,7 @@ // 05/23/02 Modified algorithm. Now only one polynomial is used // for |x-1| >= 1/256 and for |x-1| < 1/256 // 02/10/03 Reordered header: .section, .global, .proc, .align +// 03/31/05 Reformatted delimiters between data tables // // API //============================================================== diff --git a/sysdeps/ia64/fpu/e_pow.S b/sysdeps/ia64/fpu/e_pow.S index 86005f2f59..89449c79ec 100644 --- a/sysdeps/ia64/fpu/e_pow.S +++ b/sysdeps/ia64/fpu/e_pow.S @@ -1,7 +1,7 @@ .file "pow.s" -// Copyright (c) 2000 - 2003, Intel Corporation +// Copyright (c) 2000 - 2005, Intel Corporation // All rights reserved. // // Contributed 2000 by the Intel Numerics Group, Intel Corporation @@ -66,6 +66,7 @@ // 08/29/02 Improved Itanium 2 performance // 09/21/02 Added branch for |y*log(x)|<2^-11 to fix monotonicity problems. // 02/10/03 Reordered header: .section, .global, .proc, .align +// 03/31/05 Reformatted delimiters between data tables // // API //============================================================== diff --git a/sysdeps/ia64/fpu/e_powf.S b/sysdeps/ia64/fpu/e_powf.S index 4c839cba71..1406a94b65 100644 --- a/sysdeps/ia64/fpu/e_powf.S +++ b/sysdeps/ia64/fpu/e_powf.S @@ -1,7 +1,7 @@ .file "powf.s" -// Copyright (c) 2000 - 2003, Intel Corporation +// Copyright (c) 2000 - 2005, Intel Corporation // All rights reserved. // // Contributed 2000 by the Intel Numerics Group, Intel Corporation @@ -66,6 +66,7 @@ // 02/10/03 Reordered header: .section, .global, .proc, .align // 10/09/03 Modified algorithm to improve performance, reduce table size, and // fix boundary case powf(2.0,-150.0) +// 03/31/05 Reformatted delimiters between data tables // // API //============================================================== diff --git a/sysdeps/ia64/fpu/e_sinh.S b/sysdeps/ia64/fpu/e_sinh.S index 5910d4aef9..f60907b72b 100644 --- a/sysdeps/ia64/fpu/e_sinh.S +++ b/sysdeps/ia64/fpu/e_sinh.S @@ -1,7 +1,7 @@ .file "sinh.s" -// Copyright (c) 2000 - 2002, Intel Corporation +// Copyright (c) 2000 - 2005, Intel Corporation // All rights reserved. // // Contributed 2000 by the Intel Numerics Group, Intel Corporation @@ -48,6 +48,7 @@ // 05/02/01 Reworked to improve speed of all paths // 05/20/02 Cleaned up namespace and sf0 syntax // 11/20/02 Improved speed with new algorithm +// 03/31/05 Reformatted delimiters between data tables // API //============================================================== diff --git a/sysdeps/ia64/fpu/e_sinhf.S b/sysdeps/ia64/fpu/e_sinhf.S index d01d830734..6d808cb478 100644 --- a/sysdeps/ia64/fpu/e_sinhf.S +++ b/sysdeps/ia64/fpu/e_sinhf.S @@ -1,7 +1,7 @@ .file "sinhf.s" -// Copyright (c) 2000 - 2002, Intel Corporation +// Copyright (c) 2000 - 2005, Intel Corporation // All rights reserved. // // Contributed 2000 by the Intel Numerics Group, Intel Corporation @@ -48,6 +48,7 @@ // 05/02/01 Reworked to improve speed of all paths // 05/20/02 Cleaned up namespace and sf0 syntax // 11/20/02 Improved algorithm based on expf +// 03/31/05 Reformatted delimiters between data tables // // API //********************************************************************* diff --git a/sysdeps/ia64/fpu/libm_error.c b/sysdeps/ia64/fpu/libm_error.c index a7f9daefa0..24fb406a53 100644 --- a/sysdeps/ia64/fpu/libm_error.c +++ b/sysdeps/ia64/fpu/libm_error.c @@ -1,7 +1,7 @@ /* file: libm_error.c */ -// Copyright (c) 2000 - 2004, Intel Corporation +// Copyright (c) 2000 - 2005, Intel Corporation // All rights reserved. // // Contributed 2000 by the Intel Numerics Group, Intel Corporation @@ -85,6 +85,7 @@ // nextafter_underflow, nexttoward_overflow, nexttoward_underflow. // Added ISOC to set errno for nextafter and nexttoward underflow. // 12/15/04: Corrected POSIX behavior for exp, exp2, and exp10 underflow. +// 03/31/05: Added missing ALIGNIT statement to 6 float constants. #include <errno.h> #include <stdio.h> @@ -163,11 +164,17 @@ struct exceptionl excl; #define STATIC static +ALIGNIT STATIC const char float_inf[4] = {0x00,0x00,0x80,0x7F}; +ALIGNIT STATIC const char float_huge[4] = {0xFF,0xFF,0x7F,0x7F}; +ALIGNIT STATIC const char float_zero[4] = {0x00,0x00,0x00,0x00}; +ALIGNIT STATIC const char float_neg_inf[4] = {0x00,0x00,0x80,0xFF}; +ALIGNIT STATIC const char float_neg_huge[4] = {0xFF,0xFF,0x7F,0xFF}; +ALIGNIT STATIC const char float_neg_zero[4] = {0x00,0x00,0x00,0x80}; ALIGNIT STATIC const char double_inf[8] = {0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0x7F}; diff --git a/sysdeps/ia64/fpu/libm_lgamma.S b/sysdeps/ia64/fpu/libm_lgamma.S index 0df1e4bc58..6096319ba5 100644 --- a/sysdeps/ia64/fpu/libm_lgamma.S +++ b/sysdeps/ia64/fpu/libm_lgamma.S @@ -1,7 +1,7 @@ .file "libm_lgamma.s" -// Copyright (c) 2002 - 2003, Intel Corporation +// Copyright (c) 2002 - 2005, Intel Corporation // All rights reserved. // // Contributed 2002 by the Intel Numerics Group, Intel Corporation @@ -48,6 +48,7 @@ // 10/21/02 Now it returns SIGN(GAMMA(x))=-1 for negative zero // 02/10/03 Reordered header: .section, .global, .proc, .align // 07/22/03 Reformatted some data tables +// 03/31/05 Reformatted delimiters between data tables // //********************************************************************* // @@ -630,7 +631,7 @@ data8 0x7F5754D9278B51A8 // overflow boundary (first inf result) data8 0xAAAAAAAAAAAAAAAB,0x3FFB // W2=B2/2=1/12 // data8 0x3FBC756AC654273B // Q8 -data8 0xBFC001A42489AB4D // Q7 ; +data8 0xBFC001A42489AB4D // Q7 data8 0x3FC99999999A169B // Q4 data8 0xBFD00000000019AC // Q3 data8 0x3FC2492479AA0DF8 // Q6 diff --git a/sysdeps/ia64/fpu/libm_lgammaf.S b/sysdeps/ia64/fpu/libm_lgammaf.S index 04dcd63fa7..4bd92c3b26 100644 --- a/sysdeps/ia64/fpu/libm_lgammaf.S +++ b/sysdeps/ia64/fpu/libm_lgammaf.S @@ -1,7 +1,7 @@ .file "libm_lgammaf.s" -// Copyright (c) 2002 - 2003, Intel Corporation +// Copyright (c) 2002 - 2005, Intel Corporation // All rights reserved. // // Contributed 2002 by the Intel Numerics Group, Intel Corporation @@ -48,6 +48,7 @@ // 10/21/02 Now it returns SIGN(GAMMA(x))=-1 for negative zero // 02/10/03 Reordered header: .section, .global, .proc, .align // 07/22/03 Reformatted some data tables +// 03/31/05 Reformatted delimiters between data tables // //********************************************************************* // diff --git a/sysdeps/ia64/fpu/libm_lgammal.S b/sysdeps/ia64/fpu/libm_lgammal.S index 844c517785..407b3452cd 100644 --- a/sysdeps/ia64/fpu/libm_lgammal.S +++ b/sysdeps/ia64/fpu/libm_lgammal.S @@ -1,7 +1,7 @@ .file "libm_lgammal.s" -// Copyright (c) 2002 - 2003, Intel Corporation +// Copyright (c) 2002 - 2005, Intel Corporation // All rights reserved. // // Contributed 2002 by the Intel Numerics Group, Intel Corporation @@ -46,6 +46,7 @@ // 09/26/02 Algorithm description improved // 10/21/02 Now it returns SIGN(GAMMA(x))=-1 for negative zero // 02/10/03 Reordered header: .section, .global, .proc, .align +// 03/31/05 Reformatted delimiters between data tables // //********************************************************************* // diff --git a/sysdeps/ia64/fpu/libm_sincos.S b/sysdeps/ia64/fpu/libm_sincos.S index 3475b6281b..7fda2afac4 100644 --- a/sysdeps/ia64/fpu/libm_sincos.S +++ b/sysdeps/ia64/fpu/libm_sincos.S @@ -1,7 +1,7 @@ .file "libm_sincos.s" -// Copyright (c) 2002 - 2003, Intel Corporation +// Copyright (c) 2002 - 2005, Intel Corporation // All rights reserved. // // Contributed 2002 by the Intel Numerics Group, Intel Corporation @@ -48,6 +48,7 @@ // 02/10/03 Reordered header: .section, .global, .proc, .align // 08/08/03 Improved performance // 02/11/04 cis is moved to the separate file. +// 03/31/05 Reformatted delimiters between data tables // // API //============================================================== diff --git a/sysdeps/ia64/fpu/libm_sincosf.S b/sysdeps/ia64/fpu/libm_sincosf.S index fb12007af8..cf23356ef4 100644 --- a/sysdeps/ia64/fpu/libm_sincosf.S +++ b/sysdeps/ia64/fpu/libm_sincosf.S @@ -1,7 +1,7 @@ .file "libm_sincosf.s" -// Copyright (c) 2002 - 2003, Intel Corporation +// Copyright (c) 2002 - 2005, Intel Corporation // All rights reserved. // // Contributed 2002 by the Intel Numerics Group, Intel Corporation @@ -48,6 +48,7 @@ // 09/05/02 Work range is widened by reduction strengthen (2 parts of Pi/16) // 02/10/03 Reordered header: .section, .global, .proc, .align // 02/11/04 cisf is moved to the separate file. +// 03/31/05 Reformatted delimiters between data tables // API //============================================================== diff --git a/sysdeps/ia64/fpu/s_asinh.S b/sysdeps/ia64/fpu/s_asinh.S index ab01f4f570..7eba39eb40 100644 --- a/sysdeps/ia64/fpu/s_asinh.S +++ b/sysdeps/ia64/fpu/s_asinh.S @@ -1,7 +1,7 @@ .file "asinh.s" -// Copyright (c) 2000 - 2003, Intel Corporation +// Copyright (c) 2000 - 2005, Intel Corporation // All rights reserved. // // Contributed 2000 by the Intel Numerics Group, Intel Corporation @@ -46,6 +46,7 @@ // 05/20/02 Cleaned up namespace and sf0 syntax // 02/06/03 Reordered header: .section, .global, .proc, .align // 05/21/03 Improved performance, fixed to handle unorms +// 03/31/05 Reformatted delimiters between data tables // // API // ============================================================== diff --git a/sysdeps/ia64/fpu/s_atanl.S b/sysdeps/ia64/fpu/s_atanl.S index 721a38c108..1a23611307 100644 --- a/sysdeps/ia64/fpu/s_atanl.S +++ b/sysdeps/ia64/fpu/s_atanl.S @@ -1,7 +1,7 @@ .file "atanl.s" -// Copyright (c) 2000 - 2003, Intel Corporation +// Copyright (c) 2000 - 2005, Intel Corporation // All rights reserved. // // Contributed 2000 by the Intel Numerics Group, Intel Corporation @@ -51,6 +51,7 @@ // 05/20/02 Cleaned up namespace and sf0 syntax // 02/10/03 Reordered header: .section, .global, .proc, .align; // used data8 for long double table values +// 03/31/05 Reformatted delimiters between data tables // //********************************************************************* // diff --git a/sysdeps/ia64/fpu/s_cos.S b/sysdeps/ia64/fpu/s_cos.S index bf8997b4f5..fc121fce19 100644 --- a/sysdeps/ia64/fpu/s_cos.S +++ b/sysdeps/ia64/fpu/s_cos.S @@ -1,7 +1,7 @@ .file "sincos.s" -// Copyright (c) 2000 - 2004, Intel Corporation +// Copyright (c) 2000 - 2005, Intel Corporation // All rights reserved. // // Contributed 2000 by the Intel Numerics Group, Intel Corporation @@ -53,6 +53,7 @@ // 02/10/03 Reordered header: .section, .global, .proc, .align // 08/08/03 Improved performance // 10/28/04 Saved sincos_r_sincos to avoid clobber by dynamic loader +// 03/31/05 Reformatted delimiters between data tables // API //============================================================== @@ -300,7 +301,6 @@ data8 0xd4db3148750d181a , 0x00003ffe // cos( 3 pi/16) C3 data8 0xb504f333f9de6484 , 0x00003ffe // sin( 4 pi/16) S4 data8 0xb504f333f9de6484 , 0x00003ffe // cos( 4 pi/16) C4 // -// data8 0xd4db3148750d181a , 0x00003ffe // sin( 5 pi/16) C3 data8 0x8e39d9cd73464364 , 0x00003ffe // cos( 5 pi/16) S3 // @@ -313,7 +313,6 @@ data8 0xc7c5c1e34d3055b3 , 0x00003ffc // cos( 7 pi/16) S1 data8 0x8000000000000000 , 0x00003fff // sin( 8 pi/16) C0 data8 0x0000000000000000 , 0x00000000 // cos( 8 pi/16) S0 // -// data8 0xfb14be7fbae58157 , 0x00003ffe // sin( 9 pi/16) C1 data8 0xc7c5c1e34d3055b3 , 0x0000bffc // cos( 9 pi/16) -S1 // @@ -326,7 +325,6 @@ data8 0x8e39d9cd73464364 , 0x0000bffe // cos(11 pi/16) -S3 data8 0xb504f333f9de6484 , 0x00003ffe // sin(12 pi/16) S4 data8 0xb504f333f9de6484 , 0x0000bffe // cos(12 pi/16) -S4 // -// data8 0x8e39d9cd73464364 , 0x00003ffe // sin(13 pi/16) S3 data8 0xd4db3148750d181a , 0x0000bffe // cos(13 pi/16) -C3 // @@ -339,7 +337,6 @@ data8 0xfb14be7fbae58157 , 0x0000bffe // cos(15 pi/16) -C1 data8 0x0000000000000000 , 0x00000000 // sin(16 pi/16) S0 data8 0x8000000000000000 , 0x0000bfff // cos(16 pi/16) -C0 // -// data8 0xc7c5c1e34d3055b3 , 0x0000bffc // sin(17 pi/16) -S1 data8 0xfb14be7fbae58157 , 0x0000bffe // cos(17 pi/16) -C1 // @@ -352,7 +349,6 @@ data8 0xd4db3148750d181a , 0x0000bffe // cos(19 pi/16) -C3 data8 0xb504f333f9de6484 , 0x0000bffe // sin(20 pi/16) -S4 data8 0xb504f333f9de6484 , 0x0000bffe // cos(20 pi/16) -S4 // -// data8 0xd4db3148750d181a , 0x0000bffe // sin(21 pi/16) -C3 data8 0x8e39d9cd73464364 , 0x0000bffe // cos(21 pi/16) -S3 // @@ -365,7 +361,6 @@ data8 0xc7c5c1e34d3055b3 , 0x0000bffc // cos(23 pi/16) -S1 data8 0x8000000000000000 , 0x0000bfff // sin(24 pi/16) -C0 data8 0x0000000000000000 , 0x00000000 // cos(24 pi/16) S0 // -// data8 0xfb14be7fbae58157 , 0x0000bffe // sin(25 pi/16) -C1 data8 0xc7c5c1e34d3055b3 , 0x00003ffc // cos(25 pi/16) S1 // @@ -378,7 +373,6 @@ data8 0x8e39d9cd73464364 , 0x00003ffe // cos(27 pi/16) S3 data8 0xb504f333f9de6484 , 0x0000bffe // sin(28 pi/16) -S4 data8 0xb504f333f9de6484 , 0x00003ffe // cos(28 pi/16) S4 // -// data8 0x8e39d9cd73464364 , 0x0000bffe // sin(29 pi/16) -S3 data8 0xd4db3148750d181a , 0x00003ffe // cos(29 pi/16) C3 // diff --git a/sysdeps/ia64/fpu/s_cosf.S b/sysdeps/ia64/fpu/s_cosf.S index a588938eed..bcdf1b0c02 100644 --- a/sysdeps/ia64/fpu/s_cosf.S +++ b/sysdeps/ia64/fpu/s_cosf.S @@ -1,7 +1,7 @@ .file "sincosf.s" -// Copyright (c) 2000 - 2003, Intel Corporation +// Copyright (c) 2000 - 2005, Intel Corporation // All rights reserved. // // Contributed 2000 by the Intel Numerics Group, Intel Corporation @@ -51,6 +51,7 @@ // 06/03/02 Insure inexact flag set for large arg result // 09/05/02 Single precision version is made using double precision one as base // 02/10/03 Reordered header: .section, .global, .proc, .align +// 03/31/05 Reformatted delimiters between data tables // // API //============================================================== diff --git a/sysdeps/ia64/fpu/s_erf.S b/sysdeps/ia64/fpu/s_erf.S index 3abcd3e1ab..7174a197fb 100644 --- a/sysdeps/ia64/fpu/s_erf.S +++ b/sysdeps/ia64/fpu/s_erf.S @@ -1,7 +1,7 @@ .file "erf.s" -// Copyright (c) 2001 - 2003, Intel Corporation +// Copyright (c) 2001 - 2005, Intel Corporation // All rights reserved. // // Contributed 2001 by the Intel Numerics Group, Intel Corporation @@ -42,6 +42,7 @@ // 08/15/01 Initial version // 05/20/02 Cleaned up namespace and sf0 syntax // 02/06/03 Reordered header: .section, .global, .proc, .align +// 03/31/05 Reformatted delimiters between data tables // // API //============================================================== diff --git a/sysdeps/ia64/fpu/s_erfc.S b/sysdeps/ia64/fpu/s_erfc.S index 3b1b583803..addfef44c2 100644 --- a/sysdeps/ia64/fpu/s_erfc.S +++ b/sysdeps/ia64/fpu/s_erfc.S @@ -1,7 +1,7 @@ .file "erfc.s" -// Copyright (c) 2001 - 2003, Intel Corporation +// Copyright (c) 2001 - 2005, Intel Corporation // All rights reserved. // // Contributed 2001 by the Intel Numerics Group, Intel Corporation @@ -42,6 +42,7 @@ // 11/12/01 Initial version // 05/20/02 Cleaned up namespace and sf0 syntax // 02/06/03 Reordered header: .section, .global, .proc, .align +// 03/31/05 Reformatted delimiters between data tables // // API //============================================================== diff --git a/sysdeps/ia64/fpu/s_erfcf.S b/sysdeps/ia64/fpu/s_erfcf.S index e09ce98ebd..2e3eeab3c7 100644 --- a/sysdeps/ia64/fpu/s_erfcf.S +++ b/sysdeps/ia64/fpu/s_erfcf.S @@ -1,7 +1,7 @@ .file "erfcf.s" -// Copyright (c) 2002 - 2003, Intel Corporation +// Copyright (c) 2002 - 2005, Intel Corporation // All rights reserved. // // Contributed 2002 by the Intel Numerics Group, Intel Corporation @@ -42,6 +42,7 @@ // 01/17/02 Initial version // 05/20/02 Cleaned up namespace and sf0 syntax // 02/06/03 Reordered header: .section, .global, .proc, .align +// 03/31/05 Reformatted delimiters between data tables // // API //============================================================== diff --git a/sysdeps/ia64/fpu/s_erfcl.S b/sysdeps/ia64/fpu/s_erfcl.S index 11f66bcb8a..266e1e1c91 100644 --- a/sysdeps/ia64/fpu/s_erfcl.S +++ b/sysdeps/ia64/fpu/s_erfcl.S @@ -1,7 +1,7 @@ .file "erfcl.s" -// Copyright (c) 2001 - 2003, Intel Corporation +// Copyright (c) 2001 - 2005, Intel Corporation // All rights reserved. // // Contributed 2001 by the Intel Numerics Group, Intel Corporation @@ -44,6 +44,7 @@ // 05/20/02 Cleaned up namespace and sf0 syntax // 02/10/03 Reordered header: .section, .global, .proc, .align; // used data8 for long double table values +// 03/31/05 Reformatted delimiters between data tables // // API //============================================================== @@ -763,7 +764,7 @@ LOCAL_OBJECT_END(erfc_s_table) LOCAL_OBJECT_START(erfc_Q_table) // Q(z)= (P(z)- S)/S - +// // Pol0 data8 0x98325D50F9DC3499, 0x0000BFAA //A0 = +3.07358861423101280650e-26L data8 0xED35081A2494DDD9, 0x00003FF8 //A1 = +1.44779757616302832466e-02L diff --git a/sysdeps/ia64/fpu/s_erff.S b/sysdeps/ia64/fpu/s_erff.S index 204446fbdf..ed0aaac488 100644 --- a/sysdeps/ia64/fpu/s_erff.S +++ b/sysdeps/ia64/fpu/s_erff.S @@ -1,7 +1,7 @@ .file "erff.s" -// Copyright (c) 2001 - 2003, Intel Corporation +// Copyright (c) 2001 - 2005, Intel Corporation // All rights reserved. // // Contributed 2001 by the Intel Numerics Group, Intel Corporation @@ -42,6 +42,7 @@ // 08/14/01 Initial version // 05/20/02 Cleaned up namespace and sf0 syntax // 02/06/03 Reordered header: .section, .global, .proc, .align +// 03/31/05 Reformatted delimiters between data tables // // API //============================================================== diff --git a/sysdeps/ia64/fpu/s_expm1.S b/sysdeps/ia64/fpu/s_expm1.S index 5d1fd8c538..09a22bbbdd 100644 --- a/sysdeps/ia64/fpu/s_expm1.S +++ b/sysdeps/ia64/fpu/s_expm1.S @@ -1,7 +1,7 @@ .file "exp_m1.s" -// Copyright (c) 2000 - 2002, Intel Corporation +// Copyright (c) 2000 - 2005, Intel Corporation // All rights reserved. // // Contributed 2000 by the Intel Numerics Group, Intel Corporation @@ -46,6 +46,7 @@ // 07/07/01 Improved speed of all paths // 05/20/02 Cleaned up namespace and sf0 syntax // 11/20/02 Improved speed, algorithm based on exp +// 03/31/05 Reformatted delimiters between data tables // API //============================================================== diff --git a/sysdeps/ia64/fpu/s_expm1f.S b/sysdeps/ia64/fpu/s_expm1f.S index 311be06343..8996977ddb 100644 --- a/sysdeps/ia64/fpu/s_expm1f.S +++ b/sysdeps/ia64/fpu/s_expm1f.S @@ -1,7 +1,7 @@ .file "expf_m1.s" -// Copyright (c) 2000 - 2002, Intel Corporation +// Copyright (c) 2000 - 2005, Intel Corporation // All rights reserved. // // Contributed 2000 by the Intel Numerics Group, Intel Corporation @@ -46,6 +46,7 @@ // 07/07/01 Improved speed of all paths // 05/20/02 Cleaned up namespace and sf0 syntax // 11/20/02 Improved speed, algorithm based on expf +// 03/31/05 Reformatted delimiters between data tables // // // API diff --git a/sysdeps/ia64/fpu/s_log1p.S b/sysdeps/ia64/fpu/s_log1p.S index ccf0c310ad..e1e6dcc80b 100644 --- a/sysdeps/ia64/fpu/s_log1p.S +++ b/sysdeps/ia64/fpu/s_log1p.S @@ -1,7 +1,7 @@ .file "log1p.s" -// Copyright (c) 2000 - 2003, Intel Corporation +// Copyright (c) 2000 - 2005, Intel Corporation // All rights reserved. // // Contributed 2000 by the Intel Numerics Group, Intel Corporation @@ -48,6 +48,7 @@ // 10/02/02 Improved performance by basing on log algorithm // 02/10/03 Reordered header: .section, .global, .proc, .align // 04/18/03 Eliminate possible WAW dependency warning +// 03/31/05 Reformatted delimiters between data tables // // API //============================================================== diff --git a/sysdeps/ia64/fpu/s_tanf.S b/sysdeps/ia64/fpu/s_tanf.S index 98e3f76f17..193d7568a5 100644 --- a/sysdeps/ia64/fpu/s_tanf.S +++ b/sysdeps/ia64/fpu/s_tanf.S @@ -1,7 +1,7 @@ .file "tancotf.s" -// Copyright (c) 2000 - 2003, Intel Corporation +// Copyright (c) 2000 - 2005, Intel Corporation // All rights reserved. // // Contributed 2000 by the Intel Numerics Group, Intel Corporation @@ -47,6 +47,7 @@ // 11/25/02 Added explicit completer on fnorm // 02/10/03 Reordered header: .section, .global, .proc, .align // 04/17/03 Eliminated redundant stop bits +// 03/31/05 Reformatted delimiters between data tables // // APIs //============================================================== diff --git a/sysdeps/ia64/fpu/s_tanh.S b/sysdeps/ia64/fpu/s_tanh.S index 5e0c407c78..9adbc9c461 100644 --- a/sysdeps/ia64/fpu/s_tanh.S +++ b/sysdeps/ia64/fpu/s_tanh.S @@ -1,7 +1,7 @@ .file "tanh.s" -// Copyright (c) 2001 - 2003, Intel Corporation +// Copyright (c) 2001 - 2005, Intel Corporation // All rights reserved. // // Contributed 2001 by the Intel Numerics Group, Intel Corporation @@ -45,6 +45,7 @@ // 05/20/02 Cleaned up namespace and sf0 syntax // 08/14/02 Changed mli templates to mlx // 02/10/03 Reordered header: .section, .global, .proc, .align +// 03/31/05 Reformatted delimiters between data tables // // API //============================================================================== @@ -364,7 +365,6 @@ data8 0xA23A087F96846951, 0x0000BFE0 //A6 data8 0xF358D8A7FC012D5D, 0x00003FDE //A5 data8 0x98176E2309B7C73A, 0x0000BFDD //A4 // -// // Coefficients ##16..19 ("tail" coefficient tables) // Polynomial coefficients for the tanh(x), 0.25 <= |x| < 0.5 data8 0x838F209ABB9BA7B3, 0x0000BFF7 //A3 @@ -427,7 +427,6 @@ data8 0xE42327B9B0D7202F, 0x0000BFD8 //A2 data8 0xE42327BB13076BD6, 0x00003FD5 //A1 data8 0xFFFFFFFFFFF8DEE7, 0x00003FFE //A0 // -// // Polynomial coefficients for the tanh(x), 0.0 <= |x| < 0.25 // ('tanh_near_zero' path) data8 0xBF2BA5D26E479D0C //A9 @@ -440,7 +439,6 @@ data8 0x3F6D6D36C3D5B7A1 //A6 data8 0xBFABA1BA1BA19D32 //A3 data8 0x3FC1111111111108 //A2 // -// // 1.0 - 2^(-63) // ('tanh_saturation' path) data8 0xFFFFFFFFFFFFFFFF, 0x00003FFE diff --git a/sysdeps/ia64/fpu/s_tanhf.S b/sysdeps/ia64/fpu/s_tanhf.S index 344ca4ec5a..e4e91cfe63 100644 --- a/sysdeps/ia64/fpu/s_tanhf.S +++ b/sysdeps/ia64/fpu/s_tanhf.S @@ -1,7 +1,7 @@ .file "tanhf.s" -// Copyright (c) 2001 - 2003, Intel Corporation +// Copyright (c) 2001 - 2005, Intel Corporation // All rights reserved. // // Contributed 2001 by the Intel Numerics Group, Intel Corporation @@ -42,6 +42,7 @@ // 05/30/01 Initial version // 05/20/02 Cleaned up namespace and sf0 syntax // 02/10/03 Reordered header: .section, .global, .proc, .align +// 03/31/05 Reformatted delimiters between data tables // // API //============================================================== @@ -224,7 +225,6 @@ data8 0xBFD555551E8245B7 // A0 data8 0x3FC110E63F52E689 // A1 data8 0xBFAB8CD6A5B7BAFA // A2 data8 0x3F945D467FCEB553 // A3 -// // Polynomial coefficients for the tanh(x), 0.3125 <= |x| < 0.5 data8 0xBE3DCC92FCAECBB6 // A0 data8 0x3FF0000043B7D267 // A1 diff --git a/sysdeps/ia64/fpu/w_tgamma.S b/sysdeps/ia64/fpu/w_tgamma.S index e55e4e396b..24f3d11840 100644 --- a/sysdeps/ia64/fpu/w_tgamma.S +++ b/sysdeps/ia64/fpu/w_tgamma.S @@ -1,7 +1,7 @@ .file "tgamma.s" -// Copyright (c) 2001 - 2003, Intel Corporation +// Copyright (c) 2001 - 2005, Intel Corporation // All rights reserved. // // Contributed 2001 by the Intel Numerics Group, Intel Corporation @@ -45,6 +45,7 @@ // 02/10/03 Reordered header: .section, .global, .proc, .align // 04/04/03 Changed error codes for overflow and negative integers // 04/10/03 Changed code for overflow near zero handling +// 03/31/05 Reformatted delimiters between data tables // //********************************************************************* // @@ -538,7 +539,6 @@ data8 0x8646E78AABEF0255,0x00003FFF // C20 data8 0xA32AEDB62E304345,0x00003FFF // C30 data8 0xCE83E40280EE7DF0,0x00003FFF // C40 // -// //[2; 3] data8 0xC44FB47E90584083,0x00004001 // C50 data8 0xE863EE77E1C45981,0x00004001 // C60 diff --git a/sysdeps/ia64/fpu/w_tgammaf.S b/sysdeps/ia64/fpu/w_tgammaf.S index 64421ab4ee..dda0d0fe9d 100644 --- a/sysdeps/ia64/fpu/w_tgammaf.S +++ b/sysdeps/ia64/fpu/w_tgammaf.S @@ -1,7 +1,7 @@ .file "tgammaf.s" -// Copyright (c) 2001 - 2003, Intel Corporation +// Copyright (c) 2001 - 2005, Intel Corporation // All rights reserved. // // Contributed 2001 by the Intel Numerics Group, Intel Corporation @@ -46,6 +46,7 @@ // 04/04/03 Changed error codes for overflow and negative integers // 04/10/03 Changed code for overflow near zero handling // 12/16/03 Fixed parameter passing to/from error handling routine +// 03/31/05 Reformatted delimiters between data tables // //********************************************************************* // diff --git a/sysdeps/ia64/fpu/w_tgammal.S b/sysdeps/ia64/fpu/w_tgammal.S index d801ba0886..f64e213266 100644 --- a/sysdeps/ia64/fpu/w_tgammal.S +++ b/sysdeps/ia64/fpu/w_tgammal.S @@ -1,7 +1,7 @@ .file "tgammal.s" -// Copyright (c) 2002 - 2003, Intel Corporation +// Copyright (c) 2002 - 2005, Intel Corporation // All rights reserved. // // Contributed 2002 by the Intel Numerics Group, Intel Corporation @@ -45,6 +45,7 @@ // used data8 for long double table values // 03/17/03 Moved tgammal_libm_err label into .proc region // 04/10/03 Changed error codes for overflow and negative integers +// 03/31/05 Reformatted delimiters between data tables // // API //============================================================== diff --git a/sysdeps/sh/elf/configure b/sysdeps/sh/elf/configure index df45f2cde2..d38b0ece5d 100644 --- a/sysdeps/sh/elf/configure +++ b/sysdeps/sh/elf/configure @@ -5,7 +5,7 @@ if test "$usetls" != no; then # Check for support of thread-local storage handling in assembler and # linker. echo "$as_me:$LINENO: checking for SH TLS support" >&5 -echo $ECHO_N "checking for sh TLS support... $ECHO_C" >&6 +echo $ECHO_N "checking for SH TLS support... $ECHO_C" >&6 if test "${libc_cv_sh_tls+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else diff --git a/sysdeps/sparc/bits/link.h b/sysdeps/sparc/bits/link.h new file mode 100644 index 0000000000..9b8434f56f --- /dev/null +++ b/sysdeps/sparc/bits/link.h @@ -0,0 +1,100 @@ +/* Machine-specific audit interfaces for dynamic linker. SPARC version. + 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 _LINK_H +# error "Never include <bits/link.h> directly; use <link.h> instead." +#endif + +#if __WORDSIZE == 32 + +typedef struct La_sparc32_regs +{ + uint32_t lr_lreg[8]; /* %l0 through %l7 */ + uint32_t lr_reg[6]; /* %o0 through %o5 */ + uint32_t lr_sp; /* %o6 */ + uint32_t lr_ra; /* %o7 */ + uint32_t lr_struct; /* Pass-by-reference struct pointer */ +} La_sparc32_regs; + +typedef struct La_sparc32_retval +{ + uint32_t lrv_reg[2]; /* %o0 and %o1 */ + double lrv_fpreg[2]; /* %f0 and %f2 */ +} La_sparc32_retval; + +#else + +typedef struct La_sparc64_regs +{ + uint64_t lr_lreg[8]; /* %l0 through %l7 */ + uint64_t lr_reg[6]; /* %o0 through %o5 */ + uint64_t lr_sp; /* %o6 */ + uint64_t lr_ra; /* %o7 */ + double lr_fpreg[16]; /* %f0 through %f30 */ +} La_sparc64_regs; + +typedef struct La_sparc64_retval +{ + uint64_t lrv_reg[4]; /* %o0 through %o3 */ + double lrv_fprev[4]; /* %f0 through %f8 */ +} La_sparc64_retval; + +#endif + +__BEGIN_DECLS + +#if __WORDSIZE == 32 + +extern Elf32_Addr la_sparc32_gnu_pltenter (Elf32_Sym *__sym, + unsigned int __ndx, + uintptr_t *__refcook, + uintptr_t *__defcook, + La_sparc32_regs *__regs, + unsigned int *__flags, + const char *__symname, + long int *__framesizep); +extern unsigned int la_sparc32_gnu_pltexit (Elf32_Sym *__sym, + unsigned int __ndx, + uintptr_t *__refcook, + uintptr_t *__defcook, + const La_sparc32_regs *__inregs, + La_sparc32_retval *__outregs, + const char *symname); + +#else + +extern Elf64_Addr la_sparc64_gnu_pltenter (Elf64_Sym *__sym, + unsigned int __ndx, + uintptr_t *__refcook, + uintptr_t *__defcook, + La_sparc64_regs *__regs, + unsigned int *__flags, + const char *__symname, + long int *__framesizep); +extern unsigned int la_sparc64_gnu_pltexit (Elf64_Sym *__sym, + unsigned int __ndx, + uintptr_t *__refcook, + uintptr_t *__defcook, + const La_sparc64_regs *__inregs, + La_sparc64_retval *__outregs, + const char *symname); + +#endif + +__END_DECLS diff --git a/sysdeps/sparc/sparc32/dl-machine.h b/sysdeps/sparc/sparc32/dl-machine.h index d0af232d48..4ea122c46b 100644 --- a/sysdeps/sparc/sparc32/dl-machine.h +++ b/sysdeps/sparc/sparc32/dl-machine.h @@ -131,30 +131,31 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile) bits of %g1 with an offset into the .rela.plt section and jump to the beginning of the PLT. */ plt = (Elf32_Addr *) D_PTR (l, l_info[DT_PLTGOT]); - if (! profile) - rfunc = (Elf32_Addr) &_dl_runtime_resolve; - else + if (__builtin_expect(profile, 0)) { rfunc = (Elf32_Addr) &_dl_runtime_profile; - if (_dl_name_match_p (GLRO(dl_profile), l)) + if (GLRO(dl_profile) != NULL + && _dl_name_match_p (GLRO(dl_profile), l)) GL(dl_profile_map) = l; } + else + { + rfunc = (Elf32_Addr) &_dl_runtime_resolve; + } /* The beginning of the PLT does: - save %sp, -64, %sp - pltpc: call _dl_runtime_resolve - nop + sethi %hi(_dl_runtime_{resolve,profile}), %g2 + pltpc: jmpl %g2 + %lo(_dl_runtime_{resolve,profile}), %g2 + nop .word MAP - This saves the register window containing the arguments, and the - PC value (pltpc) implicitly saved in %o7 by the call points near the + The PC value (pltpc) saved in %g2 by the jmpl points near the location where we store the link_map pointer for this object. */ - plt[0] = OPCODE_SAVE_SP; - /* Construct PC-relative word address. */ - plt[1] = OPCODE_CALL | ((rfunc - (Elf32_Addr) &plt[1]) >> 2); + plt[0] = 0x05000000 | ((rfunc >> 10) & 0x003fffff); + plt[1] = 0x85c0a000 | (rfunc & 0x3ff); plt[2] = OPCODE_NOP; /* Fill call delay slot. */ plt[3] = (Elf32_Addr) l; if (__builtin_expect (l->l_info[VALIDX(DT_GNU_PRELINKED)] != NULL, 0) @@ -190,39 +191,6 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile) return lazy; } -/* This code is used in dl-runtime.c to call the `fixup' function - and then redirect to the address it returns. */ -#define TRAMPOLINE_TEMPLATE(tramp_name, fixup_name) \ - asm ( "\ - .text\n\ - .globl " #tramp_name "\n\ - .type " #tramp_name ", @function\n\ - .align 32\n\ -" #tramp_name ":\n\ - /* Set up the arguments to fixup --\n\ - %o0 = link_map out of plt0\n\ - %o1 = offset of reloc entry\n\ - %o2 = return address */\n\ - ld [%o7 + 8], %o0\n\ - srl %g1, 10, %o1\n\ - mov %i7, %o2\n\ - call " #fixup_name "\n\ - sub %o1, 4*12, %o1\n\ - jmp %o0\n\ - restore\n\ - .size " #tramp_name ", . - " #tramp_name "\n\ - .previous") - -#ifndef PROF -#define ELF_MACHINE_RUNTIME_TRAMPOLINE \ - TRAMPOLINE_TEMPLATE (_dl_runtime_resolve, fixup); \ - TRAMPOLINE_TEMPLATE (_dl_runtime_profile, profile_fixup); -#else -#define ELF_MACHINE_RUNTIME_TRAMPOLINE \ - TRAMPOLINE_TEMPLATE (_dl_runtime_resolve, fixup); \ - TRAMPOLINE_TEMPLATE (_dl_runtime_profile, fixup); -#endif - /* ELF_RTYPE_CLASS_PLT iff TYPE describes relocation of a PLT entry, so PLT entries should not be allowed to define the value. ELF_RTYPE_CLASS_NOCOPY iff TYPE should not be allowed to resolve to one @@ -406,7 +374,10 @@ elf_machine_plt_value (struct link_map *map, const Elf32_Rela *reloc, #endif /* dl_machine_h */ -#ifdef RESOLVE +#define ARCH_LA_PLTENTER sparc32_gnu_pltenter +#define ARCH_LA_PLTEXIT sparc32_gnu_pltexit + +#ifdef RESOLVE_MAP /* Perform the relocation specified by RELOC and SYM (which is fully resolved). MAP is the object containing the reloc. */ @@ -418,7 +389,10 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc, void *const reloc_addr_arg) { Elf32_Addr *const reloc_addr = reloc_addr_arg; + const Elf32_Sym *const refsym = sym; + Elf32_Addr value; const unsigned int r_type = ELF32_R_TYPE (reloc->r_info); + struct link_map *sym_map = NULL; #if !defined RTLD_BOOTSTRAP && !defined HAVE_Z_COMBRELOC /* This is defined in rtld.c, but nowhere in the static libc.a; make the @@ -429,6 +403,9 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc, weak_extern (_dl_rtld_map); #endif + if (__builtin_expect (r_type == R_SPARC_NONE, 0)) + return; + #if !defined RTLD_BOOTSTRAP || !defined HAVE_Z_COMBRELOC if (__builtin_expect (r_type == R_SPARC_RELATIVE, 0)) { @@ -436,161 +413,143 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc, if (map != &_dl_rtld_map) /* Already done in rtld itself. */ # endif *reloc_addr += map->l_addr + reloc->r_addend; + return; } - else -#endif - { -#if !defined RTLD_BOOTSTRAP && !defined RESOLVE_CONFLICT_FIND_MAP - const Elf32_Sym *const refsym = sym; -# ifdef USE_TLS - struct link_map *sym_map; -# endif #endif - Elf32_Addr value; + #ifndef RESOLVE_CONFLICT_FIND_MAP - if (sym->st_shndx != SHN_UNDEF && - ELF32_ST_BIND (sym->st_info) == STB_LOCAL) - { - value = map->l_addr; -# if defined USE_TLS && !defined RTLD_BOOTSTRAP - sym_map = map; -# endif - } - else - { -# if defined USE_TLS && !defined RTLD_BOOTSTRAP - sym_map = RESOLVE_MAP (&sym, version, r_type); - value = sym == NULL ? 0 : sym_map->l_addr + sym->st_value; -# else - value = RESOLVE (&sym, version, r_type); - if (sym) - value += sym->st_value; -# endif - } + if (__builtin_expect (ELF32_ST_BIND (sym->st_info) == STB_LOCAL, 0) + && sym->st_shndx != SHN_UNDEF) + { + value = map->l_addr; + } + else + { + sym_map = RESOLVE_MAP (&sym, version, r_type); + value = sym_map == NULL ? 0 : sym_map->l_addr + sym->st_value; + } #else - value = 0; + value = 0; #endif - value += reloc->r_addend; /* Assume copy relocs have zero addend. */ - switch (r_type) - { + value += reloc->r_addend; /* Assume copy relocs have zero addend. */ + + switch (r_type) + { #if !defined RTLD_BOOTSTRAP && !defined RESOLVE_CONFLICT_FIND_MAP - case R_SPARC_COPY: - if (sym == NULL) - /* This can happen in trace mode if an object could not be - found. */ - break; - if (sym->st_size > refsym->st_size - || (GLRO(dl_verbose) && sym->st_size < refsym->st_size)) - { - const char *strtab; + case R_SPARC_COPY: + if (sym == NULL) + /* This can happen in trace mode if an object could not be + found. */ + break; + if (sym->st_size > refsym->st_size + || (GLRO(dl_verbose) && sym->st_size < refsym->st_size)) + { + const char *strtab; - strtab = (const void *) D_PTR (map, l_info[DT_STRTAB]); - _dl_error_printf ("\ + strtab = (const void *) D_PTR (map, l_info[DT_STRTAB]); + _dl_error_printf ("\ %s: Symbol `%s' has different size in shared object, consider re-linking\n", - rtld_progname ?: "<program name unknown>", - strtab + refsym->st_name); - } - memcpy (reloc_addr_arg, (void *) value, - MIN (sym->st_size, refsym->st_size)); - break; + rtld_progname ?: "<program name unknown>", + strtab + refsym->st_name); + } + memcpy (reloc_addr_arg, (void *) value, + MIN (sym->st_size, refsym->st_size)); + break; #endif - case R_SPARC_GLOB_DAT: - case R_SPARC_32: - *reloc_addr = value; - break; - case R_SPARC_JMP_SLOT: - /* At this point we don't need to bother with thread safety, - so we can optimize the first instruction of .plt out. */ - sparc_fixup_plt (reloc, reloc_addr, value, 0); - break; + case R_SPARC_GLOB_DAT: + case R_SPARC_32: + *reloc_addr = value; + break; + case R_SPARC_JMP_SLOT: + /* At this point we don't need to bother with thread safety, + so we can optimize the first instruction of .plt out. */ + sparc_fixup_plt (reloc, reloc_addr, value, 0); + break; #if defined USE_TLS && (!defined RTLD_BOOTSTRAP || USE___THREAD) \ && !defined RESOLVE_CONFLICT_FIND_MAP - case R_SPARC_TLS_DTPMOD32: - /* Get the information from the link map returned by the - resolv function. */ - if (sym_map != NULL) - *reloc_addr = sym_map->l_tls_modid; - break; - case R_SPARC_TLS_DTPOFF32: - /* During relocation all TLS symbols are defined and used. - Therefore the offset is already correct. */ - *reloc_addr = (sym == NULL ? 0 : sym->st_value) + reloc->r_addend; - break; - case R_SPARC_TLS_TPOFF32: - /* The offset is negative, forward from the thread pointer. */ - /* We know the offset of object the symbol is contained in. - It is a negative value which will be added to the - thread pointer. */ - if (sym != NULL) - { - CHECK_STATIC_TLS (map, sym_map); - *reloc_addr = sym->st_value - sym_map->l_tls_offset - + reloc->r_addend; - } - break; + case R_SPARC_TLS_DTPMOD32: + /* Get the information from the link map returned by the + resolv function. */ + if (sym_map != NULL) + *reloc_addr = sym_map->l_tls_modid; + break; + case R_SPARC_TLS_DTPOFF32: + /* During relocation all TLS symbols are defined and used. + Therefore the offset is already correct. */ + *reloc_addr = (sym == NULL ? 0 : sym->st_value) + reloc->r_addend; + break; + case R_SPARC_TLS_TPOFF32: + /* The offset is negative, forward from the thread pointer. */ + /* We know the offset of object the symbol is contained in. + It is a negative value which will be added to the + thread pointer. */ + if (sym != NULL) + { + CHECK_STATIC_TLS (map, sym_map); + *reloc_addr = sym->st_value - sym_map->l_tls_offset + + reloc->r_addend; + } + break; # ifndef RTLD_BOOTSTRAP - case R_SPARC_TLS_LE_HIX22: - case R_SPARC_TLS_LE_LOX10: - if (sym != NULL) - { - CHECK_STATIC_TLS (map, sym_map); - value = sym->st_value - sym_map->l_tls_offset - + reloc->r_addend; - if (r_type == R_SPARC_TLS_LE_HIX22) - *reloc_addr = (*reloc_addr & 0xffc00000) | ((~value) >> 10); - else - *reloc_addr = (*reloc_addr & 0xffffe000) | (value & 0x3ff) - | 0x1c00; - } - break; + case R_SPARC_TLS_LE_HIX22: + case R_SPARC_TLS_LE_LOX10: + if (sym != NULL) + { + CHECK_STATIC_TLS (map, sym_map); + value = sym->st_value - sym_map->l_tls_offset + + reloc->r_addend; + if (r_type == R_SPARC_TLS_LE_HIX22) + *reloc_addr = (*reloc_addr & 0xffc00000) | ((~value) >> 10); + else + *reloc_addr = (*reloc_addr & 0xffffe000) | (value & 0x3ff) + | 0x1c00; + } + break; # endif #endif #ifndef RTLD_BOOTSTRAP - case R_SPARC_8: - *(char *) reloc_addr = value; - break; - case R_SPARC_16: - *(short *) reloc_addr = value; - break; - case R_SPARC_DISP8: - *(char *) reloc_addr = (value - (Elf32_Addr) reloc_addr); - break; - case R_SPARC_DISP16: - *(short *) reloc_addr = (value - (Elf32_Addr) reloc_addr); - break; - case R_SPARC_DISP32: - *reloc_addr = (value - (Elf32_Addr) reloc_addr); - break; - case R_SPARC_LO10: - *reloc_addr = (*reloc_addr & ~0x3ff) | (value & 0x3ff); - break; - case R_SPARC_WDISP30: - *reloc_addr = ((*reloc_addr & 0xc0000000) - | ((value - (unsigned int) reloc_addr) >> 2)); - break; - case R_SPARC_HI22: - *reloc_addr = (*reloc_addr & 0xffc00000) | (value >> 10); - break; - case R_SPARC_UA16: - ((unsigned char *) reloc_addr_arg) [0] = value >> 8; - ((unsigned char *) reloc_addr_arg) [1] = value; - break; - case R_SPARC_UA32: - ((unsigned char *) reloc_addr_arg) [0] = value >> 24; - ((unsigned char *) reloc_addr_arg) [1] = value >> 16; - ((unsigned char *) reloc_addr_arg) [2] = value >> 8; - ((unsigned char *) reloc_addr_arg) [3] = value; - break; + case R_SPARC_8: + *(char *) reloc_addr = value; + break; + case R_SPARC_16: + *(short *) reloc_addr = value; + break; + case R_SPARC_DISP8: + *(char *) reloc_addr = (value - (Elf32_Addr) reloc_addr); + break; + case R_SPARC_DISP16: + *(short *) reloc_addr = (value - (Elf32_Addr) reloc_addr); + break; + case R_SPARC_DISP32: + *reloc_addr = (value - (Elf32_Addr) reloc_addr); + break; + case R_SPARC_LO10: + *reloc_addr = (*reloc_addr & ~0x3ff) | (value & 0x3ff); + break; + case R_SPARC_WDISP30: + *reloc_addr = ((*reloc_addr & 0xc0000000) + | ((value - (unsigned int) reloc_addr) >> 2)); + break; + case R_SPARC_HI22: + *reloc_addr = (*reloc_addr & 0xffc00000) | (value >> 10); + break; + case R_SPARC_UA16: + ((unsigned char *) reloc_addr_arg) [0] = value >> 8; + ((unsigned char *) reloc_addr_arg) [1] = value; + break; + case R_SPARC_UA32: + ((unsigned char *) reloc_addr_arg) [0] = value >> 24; + ((unsigned char *) reloc_addr_arg) [1] = value >> 16; + ((unsigned char *) reloc_addr_arg) [2] = value >> 8; + ((unsigned char *) reloc_addr_arg) [3] = value; + break; #endif - case R_SPARC_NONE: /* Alright, Wilbur. */ - break; #if !defined RTLD_BOOTSTRAP || defined _NDEBUG - default: - _dl_reloc_bad_type (map, r_type, 0); - break; + default: + _dl_reloc_bad_type (map, r_type, 0); + break; #endif - } } } @@ -620,4 +579,4 @@ elf_machine_lazy_rel (struct link_map *map, } } -#endif /* RESOLVE */ +#endif /* RESOLVE_MAP */ diff --git a/sysdeps/sparc/sparc32/dl-trampoline.S b/sysdeps/sparc/sparc32/dl-trampoline.S new file mode 100644 index 0000000000..4b7853029a --- /dev/null +++ b/sysdeps/sparc/sparc32/dl-trampoline.S @@ -0,0 +1,155 @@ +/* PLT trampolines. Sparc 32-bit version. + 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. */ + +#include <sysdep.h> + + .text + .align 32 + + /* %g1: PLT offset loaded by PLT entry + * %g2: callers PC, which is PLT0 + 4, and we store the + * link map at PLT0 + 12, therefore we add 8 to get + * the address of the link map + */ + .globl _dl_runtime_resolve + .type _dl_runtime_resolve, @function +_dl_runtime_resolve: + save %sp, -104, %sp + ld [%g2 + 8], %o0 + srl %g1, 10, %o1 + call _dl_fixup + sub %o1, 4*12, %o1 + jmp %o0 + restore + .size _dl_runtime_resolve, .-_dl_runtime_resolve + + /* For the profiling cases we pass in our stack frame + * as the base of the La_sparc64_regs, so it looks + * like: + * %l0 %sp + * ... + * %l7 %sp + (7 * 8) + * %i0 %sp + (8 * 8) + * ... + * %i7 %sp + (15 * 8) + * %f0 %sp + (16 * 8) + * %f16 %sp + (31 * 8) + * framesize %sp + (32 * 8) + */ + + .globl _dl_profile_save_regs + .type _dl_profile_save_regs, @function +_dl_profile_save_regs: + std %l0, [%sp + ( 0 * 8)] + std %l2, [%sp + ( 1 * 8)] + std %l4, [%sp + ( 2 * 8)] + std %l6, [%sp + ( 3 * 8)] + std %i0, [%sp + ( 4 * 8)] + std %i2, [%sp + ( 5 * 8)] + std %i4, [%sp + ( 6 * 8)] + std %i6, [%sp + ( 7 * 8)] + ld [%sp + (8 * 8)], %l4 + retl + st %l4, [%sp + (8 * 8)] + .size _dl_profile_save_regs, .-_dl_profile_save_regs + + /* If we are going to call pltexit, then we must replicate + * the caller's stack frame. + * %o0: PLT resolved function address + */ + .globl _dl_profile_invoke + .type _dl_profile_invoke, @function +_dl_profile_invoke: + sub %sp, %l0, %sp +1: + srl %l0, 3, %l7 + mov %o0, %l1 + mov %i0, %o0 + mov %i1, %o1 + mov %i2, %o2 + mov %i3, %o3 + mov %i4, %o4 + mov %i5, %o5 + mov %fp, %l2 + mov %sp, %l3 +1: ldd [%l2], %g2 + add %l2, 0x8, %l2 + subcc %l7, 1, %l7 + std %g2, [%l3] + bne 1b + add %l3, 0x8, %l3 + + jmpl %l1, %o7 + nop + + std %o0, [%sp + ( 9 * 8)] + std %f0, [%sp + (10 * 8)] + + mov %l5, %o0 + mov %l6, %o1 + add %sp, %l0, %o2 + call _dl_call_pltexit + add %sp, (16 * 8), %o3 + + ldd [%sp + (9 * 8)], %i0 + + jmpl %i7 + 8, %g0 + restore + + /* %g1: PLT offset loaded by PLT entry + * %g2: callers PC, which is PLT0 + 4, and we store the + * link map at PLT0 + 12, therefore we add 8 to get + * the address of the link map + */ + .align 32 + .globl _dl_runtime_profile + .type _dl_runtime_profile, @function +_dl_runtime_profile: + cmp %fp, 0 + be,a 1f + mov 104, %g3 + sub %fp, %sp, %g3 +1: save %sp, -104, %sp + ld [%g2 + 8], %o0 + srl %g1, 10, %o1 + mov %i7, %o2 + sub %o1, 4*12, %o1 + + mov %g3, %l0 + mov %o0, %l5 + mov %o1, %l6 + + call _dl_profile_save_regs + nop + + mov %sp, %o3 + call _dl_profile_fixup + add %sp, (9 * 8), %o4 + + ld [%sp + (9 * 8)], %o1 + cmp %o1, 0 + bgeu 1f + nop + + call _dl_profile_invoke + nop + +1: jmp %o0 + restore + .size _dl_runtime_profile, .-_dl_runtime_profile diff --git a/sysdeps/sparc/sparc64/dl-machine.h b/sysdeps/sparc/sparc64/dl-machine.h index 72b88e235c..ce9b8c9dd9 100644 --- a/sysdeps/sparc/sparc64/dl-machine.h +++ b/sysdeps/sparc/sparc64/dl-machine.h @@ -18,6 +18,9 @@ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ +#ifndef dl_machine_h +#define dl_machine_h + #define ELF_MACHINE_NAME "sparc64" #include <string.h> @@ -88,7 +91,7 @@ elf_machine_load_address (void) /* We have 4 cases to handle. And we code different code sequences for each one. I love V9 code models... */ -static inline void +static inline void __attribute__ ((always_inline)) sparc64_fixup_plt (struct link_map *map, const Elf64_Rela *reloc, Elf64_Addr *reloc_addr, Elf64_Addr value, Elf64_Addr high, int t) @@ -212,7 +215,7 @@ sparc64_fixup_plt (struct link_map *map, const Elf64_Rela *reloc, } } -static inline Elf64_Addr +static inline Elf64_Addr __attribute__ ((always_inline)) elf_machine_fixup_plt (struct link_map *map, lookup_t t, const Elf64_Rela *reloc, Elf64_Addr *reloc_addr, Elf64_Addr value) @@ -233,239 +236,21 @@ elf_machine_plt_value (struct link_map *map, const Elf64_Rela *reloc, return value; } -#ifdef RESOLVE - -/* Perform the relocation specified by RELOC and SYM (which is fully resolved). - MAP is the object containing the reloc. */ - -auto inline void -__attribute__ ((always_inline)) -elf_machine_rela (struct link_map *map, const Elf64_Rela *reloc, - const Elf64_Sym *sym, const struct r_found_version *version, - void *const reloc_addr_arg) -{ - Elf64_Addr *const reloc_addr = reloc_addr_arg; - const unsigned long int r_type = ELF64_R_TYPE_ID (reloc->r_info); - -#if !defined RTLD_BOOTSTRAP || !defined HAVE_Z_COMBRELOC - if (__builtin_expect (r_type == R_SPARC_RELATIVE, 0)) - *reloc_addr = map->l_addr + reloc->r_addend; -# ifndef RTLD_BOOTSTRAP - else if (r_type == R_SPARC_NONE) /* Who is Wilbur? */ - return; -# endif - else -#endif - { -#if !defined RTLD_BOOTSTRAP && !defined RESOLVE_CONFLICT_FIND_MAP - const Elf64_Sym *const refsym = sym; -#endif - Elf64_Addr value; -#ifndef RESOLVE_CONFLICT_FIND_MAP - if (sym->st_shndx != SHN_UNDEF && - ELF64_ST_BIND (sym->st_info) == STB_LOCAL) - value = map->l_addr; - else - { - value = RESOLVE (&sym, version, r_type); - if (sym) - value += sym->st_value; - } -#else - value = 0; -#endif - value += reloc->r_addend; /* Assume copy relocs have zero addend. */ - - switch (r_type) - { -#if !defined RTLD_BOOTSTRAP && !defined RESOLVE_CONFLICT_FIND_MAP - case R_SPARC_COPY: - if (sym == NULL) - /* This can happen in trace mode if an object could not be - found. */ - break; - if (sym->st_size > refsym->st_size - || (GLRO(dl_verbose) && sym->st_size < refsym->st_size)) - { - const char *strtab; - - strtab = (const void *) D_PTR (map, l_info[DT_STRTAB]); - _dl_error_printf ("\ -%s: Symbol `%s' has different size in shared object, consider re-linking\n", - rtld_progname ?: "<program name unknown>", - strtab + refsym->st_name); - } - memcpy (reloc_addr_arg, (void *) value, - MIN (sym->st_size, refsym->st_size)); - break; -#endif - case R_SPARC_64: - case R_SPARC_GLOB_DAT: - *reloc_addr = value; - break; -#ifndef RTLD_BOOTSTRAP - case R_SPARC_8: - *(char *) reloc_addr = value; - break; - case R_SPARC_16: - *(short *) reloc_addr = value; - break; - case R_SPARC_32: - *(unsigned int *) reloc_addr = value; - break; - case R_SPARC_DISP8: - *(char *) reloc_addr = (value - (Elf64_Addr) reloc_addr); - break; - case R_SPARC_DISP16: - *(short *) reloc_addr = (value - (Elf64_Addr) reloc_addr); - break; - case R_SPARC_DISP32: - *(unsigned int *) reloc_addr = (value - (Elf64_Addr) reloc_addr); - break; - case R_SPARC_WDISP30: - *(unsigned int *) reloc_addr = - ((*(unsigned int *)reloc_addr & 0xc0000000) | - ((value - (Elf64_Addr) reloc_addr) >> 2)); - break; - - /* MEDLOW code model relocs */ - case R_SPARC_LO10: - *(unsigned int *) reloc_addr = - ((*(unsigned int *)reloc_addr & ~0x3ff) | - (value & 0x3ff)); - break; - case R_SPARC_HI22: - *(unsigned int *) reloc_addr = - ((*(unsigned int *)reloc_addr & 0xffc00000) | - (value >> 10)); - break; - case R_SPARC_OLO10: - *(unsigned int *) reloc_addr = - ((*(unsigned int *)reloc_addr & ~0x1fff) | - (((value & 0x3ff) + ELF64_R_TYPE_DATA (reloc->r_info)) & 0x1fff)); - break; - - /* MEDMID code model relocs */ - case R_SPARC_H44: - *(unsigned int *) reloc_addr = - ((*(unsigned int *)reloc_addr & 0xffc00000) | - (value >> 22)); - break; - case R_SPARC_M44: - *(unsigned int *) reloc_addr = - ((*(unsigned int *)reloc_addr & ~0x3ff) | - ((value >> 12) & 0x3ff)); - break; - case R_SPARC_L44: - *(unsigned int *) reloc_addr = - ((*(unsigned int *)reloc_addr & ~0xfff) | - (value & 0xfff)); - break; - - /* MEDANY code model relocs */ - case R_SPARC_HH22: - *(unsigned int *) reloc_addr = - ((*(unsigned int *)reloc_addr & 0xffc00000) | - (value >> 42)); - break; - case R_SPARC_HM10: - *(unsigned int *) reloc_addr = - ((*(unsigned int *)reloc_addr & ~0x3ff) | - ((value >> 32) & 0x3ff)); - break; - case R_SPARC_LM22: - *(unsigned int *) reloc_addr = - ((*(unsigned int *)reloc_addr & 0xffc00000) | - ((value >> 10) & 0x003fffff)); - break; -#endif - case R_SPARC_JMP_SLOT: -#ifdef RESOLVE_CONFLICT_FIND_MAP - /* R_SPARC_JMP_SLOT conflicts against .plt[32768+] - relocs should be turned into R_SPARC_64 relocs - in .gnu.conflict section. - r_addend non-zero does not mean it is a .plt[32768+] - reloc, instead it is the actual address of the function - to call. */ - sparc64_fixup_plt (NULL, reloc, reloc_addr, value, 0, 0); -#else - sparc64_fixup_plt (map, reloc, reloc_addr, value, - reloc->r_addend, 0); -#endif - break; -#ifndef RTLD_BOOTSTRAP - case R_SPARC_UA16: - ((unsigned char *) reloc_addr_arg) [0] = value >> 8; - ((unsigned char *) reloc_addr_arg) [1] = value; - break; - case R_SPARC_UA32: - ((unsigned char *) reloc_addr_arg) [0] = value >> 24; - ((unsigned char *) reloc_addr_arg) [1] = value >> 16; - ((unsigned char *) reloc_addr_arg) [2] = value >> 8; - ((unsigned char *) reloc_addr_arg) [3] = value; - break; - case R_SPARC_UA64: - if (! ((long) reloc_addr_arg & 3)) - { - /* Common in .eh_frame */ - ((unsigned int *) reloc_addr_arg) [0] = value >> 32; - ((unsigned int *) reloc_addr_arg) [1] = value; - break; - } - ((unsigned char *) reloc_addr_arg) [0] = value >> 56; - ((unsigned char *) reloc_addr_arg) [1] = value >> 48; - ((unsigned char *) reloc_addr_arg) [2] = value >> 40; - ((unsigned char *) reloc_addr_arg) [3] = value >> 32; - ((unsigned char *) reloc_addr_arg) [4] = value >> 24; - ((unsigned char *) reloc_addr_arg) [5] = value >> 16; - ((unsigned char *) reloc_addr_arg) [6] = value >> 8; - ((unsigned char *) reloc_addr_arg) [7] = value; - break; -#endif -#if !defined RTLD_BOOTSTRAP || defined _NDEBUG - default: - _dl_reloc_bad_type (map, r_type, 0); - break; -#endif - } - } -} - -auto inline void -__attribute__ ((always_inline)) -elf_machine_rela_relative (Elf64_Addr l_addr, const Elf64_Rela *reloc, - void *const reloc_addr_arg) -{ - Elf64_Addr *const reloc_addr = reloc_addr_arg; - *reloc_addr = l_addr + reloc->r_addend; -} - -auto inline void -__attribute__ ((always_inline)) -elf_machine_lazy_rel (struct link_map *map, - Elf64_Addr l_addr, const Elf64_Rela *reloc) -{ - switch (ELF64_R_TYPE (reloc->r_info)) - { - case R_SPARC_NONE: - break; - case R_SPARC_JMP_SLOT: - break; - default: - _dl_reloc_bad_type (map, ELFW(R_TYPE) (reloc->r_info), 1); - break; - } -} - -#endif /* RESOLVE */ - /* ELF_RTYPE_CLASS_PLT iff TYPE describes relocation of a PLT entry, so PLT entries should not be allowed to define the value. ELF_RTYPE_CLASS_NOCOPY iff TYPE should not be allowed to resolve to one of the main executable's symbols, as for a COPY reloc. */ -#define elf_machine_type_class(type) \ +#if defined USE_TLS && (!defined RTLD_BOOTSTRAP || USE___THREAD) +# define elf_machine_type_class(type) \ + ((((type) == R_SPARC_JMP_SLOT \ + || ((type) >= R_SPARC_TLS_GD_HI22 && (type) <= R_SPARC_TLS_TPOFF64)) \ + * ELF_RTYPE_CLASS_PLT) \ + | (((type) == R_SPARC_COPY) * ELF_RTYPE_CLASS_COPY)) +#else +# define elf_machine_type_class(type) \ ((((type) == R_SPARC_JMP_SLOT) * ELF_RTYPE_CLASS_PLT) \ | (((type) == R_SPARC_COPY) * ELF_RTYPE_CLASS_COPY)) +#endif /* A reloc type used for ld.so cmdline arg lookups to reject PLT entries. */ #define ELF_MACHINE_JMP_SLOT R_SPARC_JMP_SLOT @@ -490,74 +275,67 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile) extern void _dl_runtime_profile_1 (void); Elf64_Addr res0_addr, res1_addr; unsigned int *plt = (void *) D_PTR (l, l_info[DT_PLTGOT]); - int i = 0; - if (! profile) - { - res0_addr = (Elf64_Addr) &_dl_runtime_resolve_0; - res1_addr = (Elf64_Addr) &_dl_runtime_resolve_1; - } - else + if (__builtin_expect(profile, 0)) { res0_addr = (Elf64_Addr) &_dl_runtime_profile_0; res1_addr = (Elf64_Addr) &_dl_runtime_profile_1; - if (_dl_name_match_p (GLRO(dl_profile), l)) + + if (GLRO(dl_profile) != NULL + && _dl_name_match_p (GLRO(dl_profile), l)) GL(dl_profile_map) = l; } + else + { + res0_addr = (Elf64_Addr) &_dl_runtime_resolve_0; + res1_addr = (Elf64_Addr) &_dl_runtime_resolve_1; + } /* PLT0 looks like: - save %sp, -192, %sp - sethi %hh(_dl_runtime_{resolve,profile}_0), %l0 - sethi %lm(_dl_runtime_{resolve,profile}_0), %l1 - or %l0, %hm(_dl_runtime_{resolve,profile}_0), %l0 - or %l1, %lo(_dl_runtime_{resolve,profile}_0), %l1 - sllx %l0, 32, %l0 - jmpl %l0 + %l1, %l6 - sethi %hi(0xffc00), %l2 + sethi %uhi(_dl_runtime_{resolve,profile}_0), %g4 + sethi %hi(_dl_runtime_{resolve,profile}_0), %g5 + or %g4, %ulo(_dl_runtime_{resolve,profile}_0), %g4 + or %g5, %lo(_dl_runtime_{resolve,profile}_0), %g5 + sllx %g4, 32, %g4 + add %g4, %g5, %g5 + jmpl %g5, %g4 + nop */ - plt[0] = 0x9de3bf40; - plt[1] = 0x21000000 | (res0_addr >> (64 - 22)); - plt[2] = 0x23000000 | ((res0_addr >> 10) & 0x003fffff); - plt[3] = 0xa0142000 | ((res0_addr >> 32) & 0x3ff); - plt[4] = 0xa2146000 | (res0_addr & 0x3ff); - plt[5] = 0xa12c3020; - plt[6] = 0xadc40011; - plt[7] = 0x250003ff; + plt[0] = 0x09000000 | (res0_addr >> (64 - 22)); + plt[1] = 0x0b000000 | ((res0_addr >> 10) & 0x003fffff); + plt[2] = 0x88112000 | ((res0_addr >> 32) & 0x3ff); + plt[3] = 0x8a116000 | (res0_addr & 0x3ff); + plt[4] = 0x89293020; + plt[5] = 0x8a010005; + plt[6] = 0x89c14000; + plt[7] = 0x01000000; /* PLT1 looks like: - save %sp, -192, %sp - sethi %hh(_dl_runtime_{resolve,profile}_1), %l0 - sethi %lm(_dl_runtime_{resolve,profile}_1), %l1 - or %l0, %hm(_dl_runtime_{resolve,profile}_1), %l0 - or %l1, %lo(_dl_runtime_{resolve,profile}_1), %l1 - sllx %l0, 32, %l0 - jmpl %l0 + %l1, %l6 - srlx %g1, 12, %o1 + sethi %uhi(_dl_runtime_{resolve,profile}_1), %g4 + sethi %hi(_dl_runtime_{resolve,profile}_1), %g5 + or %g4, %ulo(_dl_runtime_{resolve,profile}_1), %g4 + or %g5, %lo(_dl_runtime_{resolve,profile}_1), %g5 + sllx %g4, 32, %g4 + add %g4, %g5, %g5 + jmpl %g5, %g4 + nop */ - plt[8 + 0] = 0x9de3bf40; - if (__builtin_expect (((res1_addr + 4) >> 32) & 0x3ff, 0)) - i = 1; - else - res1_addr += 4; - plt[8 + 1] = 0x21000000 | (res1_addr >> (64 - 22)); - plt[8 + 2] = 0x23000000 | ((res1_addr >> 10) & 0x003fffff); - if (__builtin_expect (i, 0)) - plt[8 + 3] = 0xa0142000 | ((res1_addr >> 32) & 0x3ff); - else - plt[8 + 3] = 0xa12c3020; - plt[8 + 4] = 0xa2146000 | (res1_addr & 0x3ff); - if (__builtin_expect (i, 0)) - plt[8 + 5] = 0xa12c3020; - plt[8 + 5 + i] = 0xadc40011; - plt[8 + 6 + i] = 0x9330700c; + plt[8] = 0x09000000 | (res1_addr >> (64 - 22)); + plt[9] = 0x0b000000 | ((res1_addr >> 10) & 0x003fffff); + plt[10] = 0x88112000 | ((res1_addr >> 32) & 0x3ff); + plt[11] = 0x8a116000 | (res1_addr & 0x3ff); + plt[12] = 0x89293020; + plt[13] = 0x8a010005; + plt[14] = 0x89c14000; + plt[15] = 0x01000000; /* Now put the magic cookie at the beginning of .PLT2 Entry .PLT3 is unused by this implementation. */ - *((struct link_map **)(&plt[16 + 0])) = l; + *((struct link_map **)(&plt[16])) = l; if (__builtin_expect (l->l_info[VALIDX(DT_GNU_PRELINKED)] != NULL, 0) || __builtin_expect (l->l_info [VALIDX (DT_GNU_LIBLISTSZ)] != NULL, 0)) @@ -604,68 +382,6 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile) return lazy; } -/* This code is used in dl-runtime.c to call the `fixup' function - and then redirect to the address it returns. */ -#define TRAMPOLINE_TEMPLATE(tramp_name, fixup_name) \ - asm ("\n" \ -" .text\n" \ -" .globl " #tramp_name "_0\n" \ -" .type " #tramp_name "_0, @function\n" \ -" .align 32\n" \ -"\t" #tramp_name "_0:\n" \ -" ! sethi %hi(1047552), %l2 - Done in .PLT0\n" \ -" ldx [%l6 + 32 + 8], %o0\n" \ -" sub %g1, %l6, %l0\n" \ -" xor %l2, -1016, %l2\n" \ -" sethi %hi(5120), %l3 ! 160 * 32\n" \ -" add %l0, %l2, %l0\n" \ -" sethi %hi(32768), %l4\n" \ -" udivx %l0, %l3, %l3\n" \ -" sllx %l3, 2, %l1\n" \ -" add %l1, %l3, %l1\n" \ -" sllx %l1, 10, %l2\n" \ -" sub %l4, 4, %l4 ! No thanks to Sun for not obeying their own ABI\n" \ -" sllx %l1, 5, %l1\n" \ -" sub %l0, %l2, %l0\n" \ -" udivx %l0, 24, %l0\n" \ -" add %l0, %l4, %l0\n" \ -" add %l1, %l0, %l1\n" \ -" add %l1, %l1, %l0\n" \ -" add %l0, %l1, %l0\n" \ -" mov %i7, %o2\n" \ -" call " #fixup_name "\n" \ -" sllx %l0, 3, %o1\n" \ -" jmp %o0\n" \ -" restore\n" \ -" .size " #tramp_name "_0, . - " #tramp_name "_0\n" \ -"\n" \ -" .globl " #tramp_name "_1\n" \ -" .type " #tramp_name "_1, @function\n" \ -" ! tramp_name_1 + 4 needs to be .align 32\n" \ -"\t" #tramp_name "_1:\n" \ -" sub %l6, 4, %l6\n" \ -" ! srlx %g1, 12, %o1 - Done in .PLT1\n" \ -" ldx [%l6 + 12], %o0\n" \ -" add %o1, %o1, %o3\n" \ -" sub %o1, 96, %o1 ! No thanks to Sun for not obeying their own ABI\n" \ -" mov %i7, %o2\n" \ -" call " #fixup_name "\n" \ -" add %o1, %o3, %o1\n" \ -" jmp %o0\n" \ -" restore\n" \ -" .size " #tramp_name "_1, . - " #tramp_name "_1\n" \ -" .previous\n"); - -#ifndef PROF -#define ELF_MACHINE_RUNTIME_TRAMPOLINE \ - TRAMPOLINE_TEMPLATE (_dl_runtime_resolve, fixup); \ - TRAMPOLINE_TEMPLATE (_dl_runtime_profile, profile_fixup); -#else -#define ELF_MACHINE_RUNTIME_TRAMPOLINE \ - TRAMPOLINE_TEMPLATE (_dl_runtime_resolve, fixup); \ - TRAMPOLINE_TEMPLATE (_dl_runtime_profile, fixup); -#endif - /* The PLT uses Elf64_Rela relocs. */ #define elf_machine_relplt elf_machine_rela @@ -766,3 +482,290 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile) " add %sp, 6*8, %sp\n" \ " .size _dl_start_user, . - _dl_start_user\n" \ " .previous\n"); + +#endif /* dl_machine_h */ + +#define ARCH_LA_PLTENTER sparc64_gnu_pltenter +#define ARCH_LA_PLTEXIT sparc64_gnu_pltexit + +#ifdef RESOLVE_MAP + +/* Perform the relocation specified by RELOC and SYM (which is fully resolved). + MAP is the object containing the reloc. */ + +auto inline void +__attribute__ ((always_inline)) +elf_machine_rela (struct link_map *map, const Elf64_Rela *reloc, + const Elf64_Sym *sym, const struct r_found_version *version, + void *const reloc_addr_arg) +{ + Elf64_Addr *const reloc_addr = reloc_addr_arg; +#if !defined RTLD_BOOTSTRAP && !defined RESOLVE_CONFLICT_FIND_MAP + const Elf64_Sym *const refsym = sym; +#endif + Elf64_Addr value; + const unsigned long int r_type = ELF64_R_TYPE_ID (reloc->r_info); +#if !defined RESOLVE_CONFLICT_FIND_MAP + struct link_map *sym_map = NULL; +#endif + +#if !defined RTLD_BOOTSTRAP && !defined HAVE_Z_COMBRELOC + /* This is defined in rtld.c, but nowhere in the static libc.a; make the + reference weak so static programs can still link. This declaration + cannot be done when compiling rtld.c (i.e. #ifdef RTLD_BOOTSTRAP) + because rtld.c contains the common defn for _dl_rtld_map, which is + incompatible with a weak decl in the same file. */ + weak_extern (_dl_rtld_map); +#endif + + if (__builtin_expect (r_type == R_SPARC_NONE, 0)) + return; + +#if !defined RTLD_BOOTSTRAP || !defined HAVE_Z_COMBRELOC + if (__builtin_expect (r_type == R_SPARC_RELATIVE, 0)) + { +# if !defined RTLD_BOOTSTRAP && !defined HAVE_Z_COMBRELOC + if (map != &_dl_rtld_map) /* Already done in rtld itself. */ +# endif + *reloc_addr += map->l_addr + reloc->r_addend; + return; + } +#endif + +#ifndef RESOLVE_CONFLICT_FIND_MAP + if (__builtin_expect (ELF64_ST_BIND (sym->st_info) == STB_LOCAL, 0) + && sym->st_shndx != SHN_UNDEF) + { + value = map->l_addr; + } + else + { + sym_map = RESOLVE_MAP (&sym, version, r_type); + value = sym_map == NULL ? 0 : sym_map->l_addr + sym->st_value; + } +#else + value = 0; +#endif + + value += reloc->r_addend; /* Assume copy relocs have zero addend. */ + + switch (r_type) + { +#if !defined RTLD_BOOTSTRAP && !defined RESOLVE_CONFLICT_FIND_MAP + case R_SPARC_COPY: + if (sym == NULL) + /* This can happen in trace mode if an object could not be + found. */ + break; + if (sym->st_size > refsym->st_size + || (GLRO(dl_verbose) && sym->st_size < refsym->st_size)) + { + const char *strtab; + + strtab = (const void *) D_PTR (map, l_info[DT_STRTAB]); + _dl_error_printf ("\ +%s: Symbol `%s' has different size in shared object, consider re-linking\n", + rtld_progname ?: "<program name unknown>", + strtab + refsym->st_name); + } + memcpy (reloc_addr_arg, (void *) value, + MIN (sym->st_size, refsym->st_size)); + break; +#endif + case R_SPARC_64: + case R_SPARC_GLOB_DAT: + *reloc_addr = value; + break; + case R_SPARC_JMP_SLOT: +#ifdef RESOLVE_CONFLICT_FIND_MAP + /* R_SPARC_JMP_SLOT conflicts against .plt[32768+] + relocs should be turned into R_SPARC_64 relocs + in .gnu.conflict section. + r_addend non-zero does not mean it is a .plt[32768+] + reloc, instead it is the actual address of the function + to call. */ + sparc64_fixup_plt (NULL, reloc, reloc_addr, value, 0, 0); +#else + sparc64_fixup_plt (map, reloc, reloc_addr, value, reloc->r_addend, 0); +#endif + break; +#if defined USE_TLS && (!defined RTLD_BOOTSTRAP || USE___THREAD) \ + && !defined RESOLVE_CONFLICT_FIND_MAP + case R_SPARC_TLS_DTPMOD64: + /* Get the information from the link map returned by the + resolv function. */ + if (sym_map != NULL) + *reloc_addr = sym_map->l_tls_modid; + break; + case R_SPARC_TLS_DTPOFF64: + /* During relocation all TLS symbols are defined and used. + Therefore the offset is already correct. */ + *reloc_addr = (sym == NULL ? 0 : sym->st_value) + reloc->r_addend; + break; + case R_SPARC_TLS_TPOFF64: + /* The offset is negative, forward from the thread pointer. */ + /* We know the offset of object the symbol is contained in. + It is a negative value which will be added to the + thread pointer. */ + if (sym != NULL) + { + CHECK_STATIC_TLS (map, sym_map); + *reloc_addr = sym->st_value - sym_map->l_tls_offset + + reloc->r_addend; + } + break; +# ifndef RTLD_BOOTSTRAP + case R_SPARC_TLS_LE_HIX22: + case R_SPARC_TLS_LE_LOX10: + if (sym != NULL) + { + CHECK_STATIC_TLS (map, sym_map); + value = sym->st_value - sym_map->l_tls_offset + + reloc->r_addend; + if (r_type == R_SPARC_TLS_LE_HIX22) + *reloc_addr = (*reloc_addr & 0xffc00000) | ((~value) >> 10); + else + *reloc_addr = (*reloc_addr & 0xffffe000) | (value & 0x3ff) + | 0x1c00; + } + break; +# endif +#endif +#ifndef RTLD_BOOTSTRAP + case R_SPARC_8: + *(char *) reloc_addr = value; + break; + case R_SPARC_16: + *(short *) reloc_addr = value; + break; + case R_SPARC_32: + *(unsigned int *) reloc_addr = value; + break; + case R_SPARC_DISP8: + *(char *) reloc_addr = (value - (Elf64_Addr) reloc_addr); + break; + case R_SPARC_DISP16: + *(short *) reloc_addr = (value - (Elf64_Addr) reloc_addr); + break; + case R_SPARC_DISP32: + *(unsigned int *) reloc_addr = (value - (Elf64_Addr) reloc_addr); + break; + case R_SPARC_WDISP30: + *(unsigned int *) reloc_addr = + ((*(unsigned int *)reloc_addr & 0xc0000000) | + ((value - (Elf64_Addr) reloc_addr) >> 2)); + break; + + /* MEDLOW code model relocs */ + case R_SPARC_LO10: + *(unsigned int *) reloc_addr = + ((*(unsigned int *)reloc_addr & ~0x3ff) | + (value & 0x3ff)); + break; + case R_SPARC_HI22: + *(unsigned int *) reloc_addr = + ((*(unsigned int *)reloc_addr & 0xffc00000) | + (value >> 10)); + break; + case R_SPARC_OLO10: + *(unsigned int *) reloc_addr = + ((*(unsigned int *)reloc_addr & ~0x1fff) | + (((value & 0x3ff) + ELF64_R_TYPE_DATA (reloc->r_info)) & 0x1fff)); + break; + + /* MEDMID code model relocs */ + case R_SPARC_H44: + *(unsigned int *) reloc_addr = + ((*(unsigned int *)reloc_addr & 0xffc00000) | + (value >> 22)); + break; + case R_SPARC_M44: + *(unsigned int *) reloc_addr = + ((*(unsigned int *)reloc_addr & ~0x3ff) | + ((value >> 12) & 0x3ff)); + break; + case R_SPARC_L44: + *(unsigned int *) reloc_addr = + ((*(unsigned int *)reloc_addr & ~0xfff) | + (value & 0xfff)); + break; + + /* MEDANY code model relocs */ + case R_SPARC_HH22: + *(unsigned int *) reloc_addr = + ((*(unsigned int *)reloc_addr & 0xffc00000) | + (value >> 42)); + break; + case R_SPARC_HM10: + *(unsigned int *) reloc_addr = + ((*(unsigned int *)reloc_addr & ~0x3ff) | + ((value >> 32) & 0x3ff)); + break; + case R_SPARC_LM22: + *(unsigned int *) reloc_addr = + ((*(unsigned int *)reloc_addr & 0xffc00000) | + ((value >> 10) & 0x003fffff)); + break; + case R_SPARC_UA16: + ((unsigned char *) reloc_addr_arg) [0] = value >> 8; + ((unsigned char *) reloc_addr_arg) [1] = value; + break; + case R_SPARC_UA32: + ((unsigned char *) reloc_addr_arg) [0] = value >> 24; + ((unsigned char *) reloc_addr_arg) [1] = value >> 16; + ((unsigned char *) reloc_addr_arg) [2] = value >> 8; + ((unsigned char *) reloc_addr_arg) [3] = value; + break; + case R_SPARC_UA64: + if (! ((long) reloc_addr_arg & 3)) + { + /* Common in .eh_frame */ + ((unsigned int *) reloc_addr_arg) [0] = value >> 32; + ((unsigned int *) reloc_addr_arg) [1] = value; + break; + } + ((unsigned char *) reloc_addr_arg) [0] = value >> 56; + ((unsigned char *) reloc_addr_arg) [1] = value >> 48; + ((unsigned char *) reloc_addr_arg) [2] = value >> 40; + ((unsigned char *) reloc_addr_arg) [3] = value >> 32; + ((unsigned char *) reloc_addr_arg) [4] = value >> 24; + ((unsigned char *) reloc_addr_arg) [5] = value >> 16; + ((unsigned char *) reloc_addr_arg) [6] = value >> 8; + ((unsigned char *) reloc_addr_arg) [7] = value; + break; +#endif +#if !defined RTLD_BOOTSTRAP || defined _NDEBUG + default: + _dl_reloc_bad_type (map, r_type, 0); + break; +#endif + } +} + +auto inline void +__attribute__ ((always_inline)) +elf_machine_rela_relative (Elf64_Addr l_addr, const Elf64_Rela *reloc, + void *const reloc_addr_arg) +{ + Elf64_Addr *const reloc_addr = reloc_addr_arg; + *reloc_addr = l_addr + reloc->r_addend; +} + +auto inline void +__attribute__ ((always_inline)) +elf_machine_lazy_rel (struct link_map *map, + Elf64_Addr l_addr, const Elf64_Rela *reloc) +{ + switch (ELF64_R_TYPE (reloc->r_info)) + { + case R_SPARC_NONE: + break; + case R_SPARC_JMP_SLOT: + break; + default: + _dl_reloc_bad_type (map, ELFW(R_TYPE) (reloc->r_info), 1); + break; + } +} + +#endif /* RESOLVE_MAP */ diff --git a/sysdeps/sparc/sparc64/dl-trampoline.S b/sysdeps/sparc/sparc64/dl-trampoline.S new file mode 100644 index 0000000000..f85527f4c4 --- /dev/null +++ b/sysdeps/sparc/sparc64/dl-trampoline.S @@ -0,0 +1,280 @@ +/* PLT trampolines. Sparc 64-bit version. + 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. */ + +#include <sysdep.h> + + .text + .align 32 + + /* %g1: PLT offset loaded by PLT entry + * %g4: callers PC, which is PLT0 + 24, therefore we + * add (32 + 8) to get the address of PLT2 which + * is where the magic cookie is stored + */ + .globl _dl_runtime_resolve_0 + .type _dl_runtime_resolve_0, @function +_dl_runtime_resolve_0: + save %sp, -192, %sp + sethi %hi(1047552), %l2 + ldx [%g4 + 32 + 8], %o0 + sub %g1, %g4, %l0 + xor %l2, -1016, %l2 + sethi %hi(5120), %l3 /* 160 * 32 */ + add %l0, %l2, %l0 + sethi %hi(32768), %l4 + udivx %l0, %l3, %l3 + sllx %l3, 2, %l1 + add %l1, %l3, %l1 + sllx %l1, 10, %l2 + sub %l4, 4, %l4 + sllx %l1, 5, %l1 + sub %l0, %l2, %l0 + udivx %l0, 24, %l0 + add %l0, %l4, %l0 + add %l1, %l0, %l1 + add %l1, %l1, %l0 + add %l0, %l1, %l0 + call _dl_fixup + sllx %l0, 3, %o1 + jmp %o0 + restore + .size _dl_runtime_resolve_0, .-_dl_runtime_resolve_0 + + /* %g1: PLT offset loaded by PLT entry + * %g4: callers PC, which is PLT1 + 24, therefore we + * add 8 to get the address of PLT2 which + * is where the magic cookie is stored + */ + .globl _dl_runtime_resolve_1 + .type _dl_runtime_resolve_1, @function +_dl_runtime_resolve_1: + save %sp, -192, %sp + srlx %g1, 12, %o1 + ldx [%g4 + 8], %o0 + add %o1, %o1, %o3 + sub %o1, 96, %o1 + call _dl_fixup + add %o1, %o3, %o1 + jmp %o0 + restore + .size _dl_runtime_resolve_1, .-_dl_runtime_resolve_1 + + /* For the profiling cases we pass in our stack frame + * as the base of the La_sparc64_regs, so it looks + * like: + * %l0 %sp + * ... + * %l7 %sp + (7 * 8) + * %i0 %sp + (8 * 8) + * ... + * %i7 %sp + (15 * 8) + * %f0 %sp + (16 * 8) + * %f16 %sp + (31 * 8) + * framesize %sp + (32 * 8) + */ + + .globl _dl_profile_save_regs + .type _dl_profile_save_regs, @function +_dl_profile_save_regs: + stx %l0, [%sp + STACK_BIAS + ( 0 * 8)] + stx %l1, [%sp + STACK_BIAS + ( 1 * 8)] + stx %l2, [%sp + STACK_BIAS + ( 2 * 8)] + stx %l3, [%sp + STACK_BIAS + ( 3 * 8)] + stx %l4, [%sp + STACK_BIAS + ( 4 * 8)] + stx %l5, [%sp + STACK_BIAS + ( 5 * 8)] + stx %l6, [%sp + STACK_BIAS + ( 6 * 8)] + stx %l7, [%sp + STACK_BIAS + ( 7 * 8)] + stx %i0, [%sp + STACK_BIAS + ( 8 * 8)] + stx %i1, [%sp + STACK_BIAS + ( 9 * 8)] + stx %i2, [%sp + STACK_BIAS + (10 * 8)] + stx %i3, [%sp + STACK_BIAS + (11 * 8)] + stx %i4, [%sp + STACK_BIAS + (12 * 8)] + stx %i5, [%sp + STACK_BIAS + (13 * 8)] + stx %i6, [%sp + STACK_BIAS + (14 * 8)] + stx %i7, [%sp + STACK_BIAS + (15 * 8)] + std %f0, [%sp + STACK_BIAS + (16 * 8)] + std %f2, [%sp + STACK_BIAS + (17 * 8)] + std %f4, [%sp + STACK_BIAS + (18 * 8)] + std %f6, [%sp + STACK_BIAS + (19 * 8)] + std %f8, [%sp + STACK_BIAS + (20 * 8)] + std %f10, [%sp + STACK_BIAS + (21 * 8)] + std %f12, [%sp + STACK_BIAS + (22 * 8)] + std %f14, [%sp + STACK_BIAS + (23 * 8)] + std %f16, [%sp + STACK_BIAS + (24 * 8)] + std %f18, [%sp + STACK_BIAS + (25 * 8)] + std %f20, [%sp + STACK_BIAS + (26 * 8)] + std %f22, [%sp + STACK_BIAS + (27 * 8)] + std %f24, [%sp + STACK_BIAS + (28 * 8)] + std %f26, [%sp + STACK_BIAS + (29 * 8)] + std %f28, [%sp + STACK_BIAS + (30 * 8)] + retl + std %f30, [%sp + STACK_BIAS + (31 * 8)] + .size _dl_profile_save_regs, .-_dl_profile_save_regs + + /* If we are going to call pltexit, then we must replicate + * the caller's stack frame. + * %o0: PLT resolved function address + */ + .globl _dl_profile_invoke + .type _dl_profile_invoke, @function +_dl_profile_invoke: + sub %sp, %l0, %sp +1: + srlx %l0, 3, %l7 + mov %o0, %l1 + mov %i0, %o0 + mov %i1, %o1 + mov %i2, %o2 + mov %i3, %o3 + mov %i4, %o4 + mov %i5, %o5 + add %fp, STACK_BIAS, %l2 + add %sp, STACK_BIAS, %l3 +1: ldx [%l2], %l4 + add %l2, 0x8, %l2 + subcc %l7, 1, %l7 + stx %l4, [%l3] + bne,pt %xcc, 1b + add %l3, 0x8, %l3 + + jmpl %l1, %o7 + nop + + stx %o0, [%sp + STACK_BIAS + (16 * 8)] + stx %o1, [%sp + STACK_BIAS + (17 * 8)] + stx %o2, [%sp + STACK_BIAS + (18 * 8)] + stx %o3, [%sp + STACK_BIAS + (19 * 8)] + std %f0, [%sp + STACK_BIAS + (20 * 8)] + std %f2, [%sp + STACK_BIAS + (21 * 8)] + std %f4, [%sp + STACK_BIAS + (22 * 8)] + std %f8, [%sp + STACK_BIAS + (23 * 8)] + + mov %l5, %o0 + mov %l6, %o1 + add %sp, %l0, %o2 + add %sp, STACK_BIAS + (16 * 8), %o3 + call _dl_call_pltexit + add %o2, STACK_BIAS, %o2 + + ldx [%sp + STACK_BIAS + (16 * 8)], %i0 + ldx [%sp + STACK_BIAS + (17 * 8)], %i1 + ldx [%sp + STACK_BIAS + (18 * 8)], %i2 + ldx [%sp + STACK_BIAS + (19 * 8)], %i3 + + jmpl %i7 + 8, %g0 + restore + + /* %g1: PLT offset loaded by PLT entry + * %g4: callers PC, which is PLT0 + 24, therefore we + * add (32 + 8) to get the address of PLT2 which + * is where the magic cookie is stored + */ + .align 32 + .globl _dl_runtime_profile_0 + .type _dl_runtime_profile_0, @function +_dl_runtime_profile_0: + brz,a,pn %fp, 1f + mov 192, %g5 + sub %fp, %sp, %g5 +1: save %sp, -336, %sp + sethi %hi(1047552), %l2 + ldx [%g4 + 32 + 8], %o0 + sub %g1, %g4, %l0 + xor %l2, -1016, %l2 + sethi %hi(5120), %l3 /* 160 * 32 */ + add %l0, %l2, %l0 + sethi %hi(32768), %l4 + udivx %l0, %l3, %l3 + sllx %l3, 2, %l1 + add %l1, %l3, %l1 + sllx %l1, 10, %l2 + sub %l4, 4, %l4 + sllx %l1, 5, %l1 + sub %l0, %l2, %l0 + udivx %l0, 24, %l0 + add %l0, %l4, %l0 + add %l1, %l0, %l1 + add %l1, %l1, %l0 + add %l0, %l1, %l0 + + mov %i7, %o2 + sllx %l0, 3, %o1 + + mov %g5, %l0 + mov %o0, %l5 + mov %o1, %l6 + + call _dl_profile_save_regs + nop + + add %sp, STACK_BIAS, %o3 + call _dl_profile_fixup + add %sp, (STACK_BIAS + (32 * 8)), %o4 + + ldx [%sp + STACK_BIAS + (32 * 8)], %o1 + brgez,pt %o1, 1f + nop + + call _dl_profile_invoke + nop + +1: jmp %o0 + restore + .size _dl_runtime_profile_0, .-_dl_runtime_profile_0 + + /* %g1: PLT offset loaded by PLT entry + * %g4: callers PC, which is PLT1 + 24, therefore we + * add 8 to get the address of PLT2 which + * is where the magic cookie is stored + */ + .globl _dl_runtime_profile_1 + .type _dl_runtime_profile_1, @function +_dl_runtime_profile_1: + brz,a,pn %fp, 1f + mov 192, %g5 + sub %fp, %sp, %g5 +1: save %sp, -336, %sp + srlx %g1, 12, %o1 + ldx [%g4 + 8], %o0 + add %o1, %o1, %o3 + sub %o1, 96, %o1 + mov %i7, %o2 + add %o1, %o3, %o1 + + mov %g5, %l0 + mov %o0, %l5 + mov %o1, %l6 + + call _dl_profile_save_regs + nop + + add %sp, STACK_BIAS, %o3 + call _dl_profile_fixup + add %sp, (STACK_BIAS + (32 * 8)), %o4 + + ldx [%sp + STACK_BIAS + (32 * 8)], %o1 + brgez,pt %o1, 1f + nop + + call _dl_profile_invoke + nop + +1: jmp %o0 + restore + .size _dl_runtime_resolve_1, .-_dl_runtime_resolve_1 diff --git a/sysdeps/unix/sysv/linux/configure b/sysdeps/unix/sysv/linux/configure index d059143396..325073c62c 100644 --- a/sysdeps/unix/sysv/linux/configure +++ b/sysdeps/unix/sysv/linux/configure @@ -138,6 +138,10 @@ case "$machine" in arch_minimum_kernel=2.3.99 libc_cv_gcc_unwind_find_fde=yes ;; + sparc/sparc64*) + libc_cv_gcc_unwind_find_fde=yes + arch_minimum_kernel=2.4.21 + ;; sparc*) libc_cv_gcc_unwind_find_fde=yes arch_minimum_kernel=2.0.10 diff --git a/sysdeps/unix/sysv/linux/configure.in b/sysdeps/unix/sysv/linux/configure.in index e3fccb4c9b..88feb868fe 100644 --- a/sysdeps/unix/sysv/linux/configure.in +++ b/sysdeps/unix/sysv/linux/configure.in @@ -98,6 +98,10 @@ case "$machine" in arch_minimum_kernel=2.3.99 libc_cv_gcc_unwind_find_fde=yes ;; + sparc/sparc64*) + libc_cv_gcc_unwind_find_fde=yes + arch_minimum_kernel=2.4.21 + ;; sparc*) libc_cv_gcc_unwind_find_fde=yes arch_minimum_kernel=2.0.10 diff --git a/sysdeps/unix/sysv/linux/dl-osinfo.h b/sysdeps/unix/sysv/linux/dl-osinfo.h index dfb4cde72d..befa804cb1 100644 --- a/sysdeps/unix/sysv/linux/dl-osinfo.h +++ b/sysdeps/unix/sysv/linux/dl-osinfo.h @@ -43,6 +43,45 @@ dl_fatal (const char *str) static inline int __attribute__ ((always_inline)) _dl_discover_osversion (void) { +#if (defined NEED_DL_SYSINFO || defined NEED_DL_SYSINFO_DSO) && defined SHARED + if (GLRO(dl_sysinfo_map) != NULL) + { + /* If the kernel-supplied DSO contains a note indicating the kernel's + version, we don't need to call uname or parse any strings. */ + + static const struct + { + ElfW(Word) vendorlen; + ElfW(Word) datalen; + ElfW(Word) type; + char vendor[8]; + } expected_note = { sizeof "Linux", sizeof (ElfW(Word)), 0, "Linux" }; + const ElfW(Phdr) *const phdr = GLRO(dl_sysinfo_map)->l_phdr; + const ElfW(Word) phnum = GLRO(dl_sysinfo_map)->l_phnum; + for (uint_fast16_t i = 0; i < phnum; ++i) + if (phdr[i].p_type == PT_NOTE) + { + const ElfW(Addr) start = (phdr[i].p_vaddr + + GLRO(dl_sysinfo_map)->l_addr); + const struct + { + ElfW(Word) vendorlen; + ElfW(Word) datalen; + ElfW(Word) type; + } *note = (const void *) start; + while ((ElfW(Addr)) (note + 1) - start < phdr[i].p_memsz) + { + if (!memcmp (note, &expected_note, sizeof expected_note)) + return *(const ElfW(Word) *) ((const void *) note + + sizeof expected_note); +#define ROUND(len) (((len) + sizeof (ElfW(Word)) - 1) & -sizeof (ElfW(Word))) + note = ((const void *) (note + 1) + + ROUND (note->vendorlen) + ROUND (note->datalen)); + } + } + } +#endif + char bufmem[64]; char *buf = bufmem; unsigned int version; diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/clone.S b/sysdeps/unix/sysv/linux/sparc/sparc32/clone.S index 66cdbf3ca7..4d8fdb8200 100644 --- a/sysdeps/unix/sysv/linux/sparc/sparc32/clone.S +++ b/sysdeps/unix/sysv/linux/sparc/sparc32/clone.S @@ -40,11 +40,19 @@ __clone: save %sp,-96,%sp /* sanity check arguments */ - tst %i0 + orcc %i0,%g0,%g2 be .Lerror orcc %i1,%g0,%o1 be .Lerror mov %i2,%o0 + + /* The child_stack is the top of the stack, allocate one + whole stack frame from that as this is what the kernel + expects. */ + sub %o1, 96, %o1 + mov %i3, %g3 + mov %i2, %g4 + /* ptid */ mov %i4,%o2 /* tls */ @@ -76,19 +84,21 @@ __clone: __thread_start: #ifdef RESET_PID sethi %hi(CLONE_THREAD), %l0 - andcc %i2, %l0, %g0 + andcc %g4, %l0, %g0 bne 1f - andcc %i2, CLONE_VM, %g0 + andcc %g4, CLONE_VM, %g0 bne,a 2f mov -1,%o0 set __NR_getpid,%g1 ta 0x10 -2: st %o0,[%g7 + PID] +2: + st %o0,[%g7 + PID] st %o0,[%g7 + TID] 1: #endif - call %i0 - mov %i3,%o0 + mov %g0, %fp /* terminate backtrace */ + call %g2 + mov %g3,%o0 call _exit,0 nop diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/clone.S b/sysdeps/unix/sysv/linux/sparc/sparc64/clone.S index a7c248b2e8..f6134599e2 100644 --- a/sysdeps/unix/sysv/linux/sparc/sparc64/clone.S +++ b/sysdeps/unix/sysv/linux/sparc/sparc64/clone.S @@ -22,8 +22,16 @@ #include <asm/errno.h> #include <asm/unistd.h> +#include <tcb-offsets.h> -/* int clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg); */ +#define CLONE_VM 0x00000100 +#define CLONE_THREAD 0x00010000 + +/* int clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg, + pid_t *ptid, void *tls, pid_t *ctid); */ + + .register %g2,#scratch + .register %g3,#scratch .text .align 4 @@ -34,22 +42,31 @@ __clone: save %sp, -192, %sp /* sanity check arguments */ - brz,pn %i0, 99f - mov %i0, %l0 /* save fn */ - brz,pn %i1, 99f - mov %i3, %l3 /* save arg */ + brz,pn %i0, 99f /* fn non-NULL? */ + mov %i0, %g2 + brz,pn %i1, 99f /* child_stack non-NULL? */ + mov %i2, %o0 /* clone flags */ + + /* The child_stack is the top of the stack, allocate one + whole stack frame from that as this is what the kernel + expects. Also, subtract STACK_BIAS. */ + sub %i1, 192 + 0x7ff, %o1 + mov %i3, %g3 + mov %i2, %g4 + + mov %i4,%o2 /* PTID */ + mov %i5,%o3 /* TLS */ + ldx [%fp+0x7ff+176],%o4 /* CTID */ /* Do the system call */ - sub %i1, 0x7ff, %o1 - mov %i2, %o0 set __NR_clone, %g1 ta 0x6d bcs,pn %xcc, 99f nop brnz,pn %o1, __thread_start - mov %o0, %i0 + nop ret - restore + restore %o0, %g0, %o0 99: #ifndef _LIBC_REENTRANT #ifdef PIC @@ -77,10 +94,22 @@ __clone: .type __thread_start,@function __thread_start: +#ifdef RESET_PID + sethi %hi(CLONE_THREAD), %l0 + andcc %g4, %l0, %g0 + bne,pt %icc, 1f + andcc %g4, CLONE_VM, %g0 + bne,a,pn %icc, 2f + mov -1,%o0 + set __NR_getpid,%g1 + ta 0x6d +2: st %o0,[%g7 + PID] + st %o0,[%g7 + TID] +1: +#endif mov %g0, %fp /* terminate backtrace */ - sub %sp, 6*8, %sp /* provide arg storage */ - call %l0 - mov %l3,%o0 + call %g2 + mov %g3,%o0 call _exit,0 nop .size __thread_start, .-__thread_start diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/pause.c b/sysdeps/unix/sysv/linux/sparc/sparc64/pause.c index 2ec5bd39ad..40fab28d47 100644 --- a/sysdeps/unix/sysv/linux/sparc/sparc64/pause.c +++ b/sysdeps/unix/sysv/linux/sparc/sparc64/pause.c @@ -1 +1,47 @@ -#include <sysdeps/posix/pause.c> +/* pause -- suspend the process until a signal arrives. POSIX.1 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. */ + +#include <errno.h> +#include <signal.h> +#include <unistd.h> +#include <sysdep-cancel.h> + +#include <sysdep.h> +#include <sys/syscall.h> +#include <bp-checks.h> + +/* Suspend the process until a signal arrives. + This always returns -1 and sets errno to EINTR. */ +int +__libc_pause (void) +{ + sigset_t set; + + __sigemptyset (&set); + INLINE_SYSCALL (rt_sigprocmask, 4, SIG_BLOCK, CHECK_SIGSET (NULL), + CHECK_SIGSET_NULL_OK (&set), _NSIG / 8); + + /* pause is a cancellation point, but so is sigsuspend. + So no need for anything special here. */ + + return __sigsuspend (&set); +} +weak_alias (__libc_pause, pause) + +LIBC_CANCEL_HANDLED (); /* sigsuspend handles our cancellation. */ diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/sysdep.h b/sysdeps/unix/sysv/linux/sparc/sparc64/sysdep.h index 3c6492aeca..071aa3a310 100644 --- a/sysdeps/unix/sysv/linux/sparc/sparc64/sysdep.h +++ b/sysdeps/unix/sysv/linux/sparc/sparc64/sysdep.h @@ -85,11 +85,54 @@ SYSCALL_ERROR_HANDLER_ENTRY(__syscall_error_handler) \ sethi %hi(_GLOBAL_OFFSET_TABLE_-4), %l7; \ call __sparc64.get_pic.l7; \ add %l7, %lo(_GLOBAL_OFFSET_TABLE_+4), %l7; \ - ldx [%l7 + rtld_errno], %l0; \ + sethi %hi(rtld_errno), %g1; \ + or %g1, %lo(rtld_errno), %g1; \ + ldx [%l7 + %g1], %l0; \ st %i0, [%l0]; \ jmpl %i7+8, %g0; \ restore %g0, -1, %o0; \ .previous; +#elif USE___THREAD +# ifndef NOT_IN_libc +# define SYSCALL_ERROR_ERRNO __libc_errno +# else +# define SYSCALL_ERROR_ERRNO errno +# endif +# ifdef SHARED +# define SYSCALL_ERROR_HANDLER \ + .section .gnu.linkonce.t.__sparc64.get_pic.l7,"ax",@progbits; \ + .globl __sparc64.get_pic.l7; \ + .hidden __sparc64.get_pic.l7; \ + .type __sparc64.get_pic.l7,@function; \ +__sparc64.get_pic.l7: \ + retl; \ + add %o7, %l7, %l7; \ + .previous; \ +SYSCALL_ERROR_HANDLER_ENTRY(__syscall_error_handler) \ + save %sp,-192,%sp; \ + sethi %tie_hi22(SYSCALL_ERROR_ERRNO), %l1; \ + sethi %hi(_GLOBAL_OFFSET_TABLE_-4), %l7; \ + call __sparc64.get_pic.l7; \ + add %l7, %lo(_GLOBAL_OFFSET_TABLE_+4), %l7; \ + add %l1, %tie_lo10(SYSCALL_ERROR_ERRNO), %l1; \ + ldx [%l7 + %l1], %l1, %tie_ldx(SYSCALL_ERROR_ERRNO); \ + st %i0, [%g7 + %l1], %tie_add(SYSCALL_ERROR_ERRNO); \ + jmpl %i7+8, %g0; \ + restore %g0, -1, %o0; \ + .previous; +# else +# define SYSCALL_ERROR_HANDLER \ +SYSCALL_ERROR_HANDLER_ENTRY(__syscall_error_handler) \ + sethi %tie_hi22(SYSCALL_ERROR_ERRNO), %g1; \ + sethi %hi(_GLOBAL_OFFSET_TABLE_), %g2; \ + add %g1, %tie_lo10(SYSCALL_ERROR_ERRNO), %g1; \ + add %g2, %lo(_GLOBAL_OFFSET_TABLE_), %g2; \ + ldx [%g2 + %g1], %g1, %tie_ldx(SYSCALL_ERROR_ERRNO); \ + st %o0, [%g7 + %g1], %tie_add(SYSCALL_ERROR_ERRNO); \ + jmpl %o7+8, %g0; \ + mov -1, %o0; \ + .previous; +# endif #else # define SYSCALL_ERROR_HANDLER \ SYSCALL_ERROR_HANDLER_ENTRY(__syscall_error_handler) \ |