From d57a3f0e0219dec6406f3477fe2eee21054c7e9c Mon Sep 17 00:00:00 2001 From: Ulrich Drepper Date: Fri, 15 Aug 2003 03:58:56 +0000 Subject: [PATCH] Update. 2003-08-11 Carlos O'Donell * dlfcn/default.c (main): Cast dlsym loaded value to same type as main. Address passed to test_in_mod1 and test_in_mod2 without casting. * dlfcn/defaultmod1.c: Change prototype of test_in_mod1. (test_in_mod1): Cast dlsym loaded value to same type as mainp. * dlfcn/defaultmod2.c: Change prototype of test_in_mod2. (test_in_mod2): Cast dlsym loaded value to same type as mainp. 2003-08-15 Jakub Jelinek * sysdeps/sparc/sparc32/elf/configure.in (libc_cv_sparc32_tls): Change quotes before using []. * sysdeps/unix/sysv/linux/sparc/sys/user.h: New file. * sysdeps/sparc/sparc32/bits/atomic.h (__sparc32_atomic_lock): Renamed to... (__sparc32_atomic_locks): ...this. Change into 64-byte array. (__sparc32_atomic_do_lock, __sparc32_atomic_do_unlock): Add addr argument. Select one of 64 locks from address bits. (atomic_compare_and_exchange_val_acq, atomic_compare_and_exchange_bool_acq): Pass memory address to __sparc32_atomic_do_{,un}lock. --- ChangeLog | 25 +++++++ dlfcn/default.c | 6 +- dlfcn/defaultmod1.c | 6 +- dlfcn/defaultmod2.c | 6 +- sysdeps/sparc/sparc32/bits/atomic.h | 30 +++++---- sysdeps/sparc/sparc32/elf/configure | 2 +- sysdeps/unix/sysv/linux/sparc/sys/user.h | 85 ++++++++++++++++++++++++ 7 files changed, 138 insertions(+), 22 deletions(-) create mode 100644 sysdeps/unix/sysv/linux/sparc/sys/user.h diff --git a/ChangeLog b/ChangeLog index d3f16d0634..8a2b8c0971 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,28 @@ +2003-08-11 Carlos O'Donell + + * dlfcn/default.c (main): Cast dlsym loaded value to same type as main. + Address passed to test_in_mod1 and test_in_mod2 without casting. + * dlfcn/defaultmod1.c: Change prototype of test_in_mod1. + (test_in_mod1): Cast dlsym loaded value to same type as mainp. + * dlfcn/defaultmod2.c: Change prototype of test_in_mod2. + (test_in_mod2): Cast dlsym loaded value to same type as mainp. + +2003-08-15 Jakub Jelinek + + * sysdeps/sparc/sparc32/elf/configure.in (libc_cv_sparc32_tls): + Change quotes before using []. + + * sysdeps/unix/sysv/linux/sparc/sys/user.h: New file. + + * sysdeps/sparc/sparc32/bits/atomic.h (__sparc32_atomic_lock): + Renamed to... + (__sparc32_atomic_locks): ...this. Change into 64-byte array. + (__sparc32_atomic_do_lock, __sparc32_atomic_do_unlock): Add addr + argument. Select one of 64 locks from address bits. + (atomic_compare_and_exchange_val_acq, + atomic_compare_and_exchange_bool_acq): Pass memory address to + __sparc32_atomic_do_{,un}lock. + 2003-08-14 Ulrich Drepper * assert/assert.h (assert): Use !! in front of expression to allow diff --git a/dlfcn/default.c b/dlfcn/default.c index e5d5275ff5..eeed5a950a 100644 --- a/dlfcn/default.c +++ b/dlfcn/default.c @@ -36,7 +36,7 @@ main (int argc, char *argv[]) printf ("%s: main not found\n", __FILE__); result = 1; } - else if (p != (void *) &main) + else if ((int (*)(int, char **))p != main) { printf ("%s: wrong address returned for main\n", __FILE__); result = 1; @@ -72,9 +72,9 @@ main (int argc, char *argv[]) else printf ("%s: found_in_mod2 correctly found\n", __FILE__); - result |= test_in_mod1 ((void *) &main); + result |= test_in_mod1 (main); - result |= test_in_mod2 ((void *) &main); + result |= test_in_mod2 (main); return result; } diff --git a/dlfcn/defaultmod1.c b/dlfcn/defaultmod1.c index 9f330b7f29..47d229d6b0 100644 --- a/dlfcn/defaultmod1.c +++ b/dlfcn/defaultmod1.c @@ -9,9 +9,9 @@ found_in_mod1 (void) } -extern int test_in_mod1 (void *mainp); +extern int test_in_mod1 (int (*mainp)(int, char **)); int -test_in_mod1 (void *mainp) +test_in_mod1 (int (*mainp)(int, char **)) { int (*ifp) (void); void *p; @@ -24,7 +24,7 @@ test_in_mod1 (void *mainp) printf ("%s: main not found\n", __FILE__); result = 1; } - else if (p != mainp) + else if ((int (*)(int, char **))p != mainp) { printf ("%s: wrong address returned for main\n", __FILE__); result = 1; diff --git a/dlfcn/defaultmod2.c b/dlfcn/defaultmod2.c index c8615e2dc3..e0b170815c 100644 --- a/dlfcn/defaultmod2.c +++ b/dlfcn/defaultmod2.c @@ -16,9 +16,9 @@ found_in_mod2 (void) } -extern int test_in_mod2 (void *mainp); +extern int test_in_mod2 (int (*mainp)(int, char **)); int -test_in_mod2 (void *mainp) +test_in_mod2 (int (*mainp)(int, char **)) { int (*ifp) (void); void *p; @@ -31,7 +31,7 @@ test_in_mod2 (void *mainp) printf ("%s: main not found\n", __FILE__); result = 1; } - else if (p != mainp) + else if ((int (*)(int, char **))p != mainp) { printf ("%s: wrong address returned for main\n", __FILE__); result = 1; diff --git a/sysdeps/sparc/sparc32/bits/atomic.h b/sysdeps/sparc/sparc32/bits/atomic.h index c4e0abfe06..00d799392b 100644 --- a/sysdeps/sparc/sparc32/bits/atomic.h +++ b/sysdeps/sparc/sparc32/bits/atomic.h @@ -22,28 +22,34 @@ #define _BITS_ATOMIC_H 1 /* We have no compare and swap, just test and set. - The following implementation contends on one single global lock + The following implementation contends on 64 global locks per library and assumes no variable will be accessed using atomic.h macros from two different libraries. */ -volatile unsigned char __sparc32_atomic_lock - __attribute__ ((nocommon, section (".gnu.linkonce.b.__sparc32_atomic_lock"), +volatile unsigned char __sparc32_atomic_locks[64] + __attribute__ ((nocommon, section (".gnu.linkonce.b.__sparc32_atomic_locks"), visibility ("hidden"))); -#define __sparc32_atomic_do_lock() \ +#define __sparc32_atomic_do_lock(addr) \ do \ { \ unsigned int __old_lock; \ + unsigned int __idx = (((long) addr >> 2) ^ ((long) addr >> 12)) \ + & 63; \ do \ __asm ("ldstub %1, %0" \ - : "=r" (__old_lock), "=m" (__sparc32_atomic_lock) \ - : "m" (__sparc32_atomic_lock)); \ + : "=r" (__old_lock), \ + "=m" (__sparc32_atomic_locks[__idx]) \ + : "m" (__sparc32_atomic_locks[__idx])); \ while (__old_lock); \ } \ while (0) -#define __sparc32_atomic_do_unlock() \ - do __sparc32_atomic_lock = 0; while (0) +#define __sparc32_atomic_do_unlock(addr) \ + do \ + __sparc32_atomic_locks[(((long) addr >> 2) \ + ^ ((long) addr >> 12)) & 63] = 0; \ + while (0) /* The only basic operation needed is compare and exchange. */ #define atomic_compare_and_exchange_val_acq(mem, newval, oldval) \ @@ -51,11 +57,11 @@ volatile unsigned char __sparc32_atomic_lock __typeof (*mem) __acev_ret; \ __typeof (*mem) __acev_newval = (newval); \ \ - __sparc32_atomic_do_lock (); \ + __sparc32_atomic_do_lock (__acev_memp); \ __acev_ret = *__acev_memp; \ if (__acev_ret == (oldval)) \ *__acev_memp = __acev_newval; \ - __sparc32_atomic_do_unlock (); \ + __sparc32_atomic_do_unlock (__acev_memp); \ __acev_ret; }) #define atomic_compare_and_exchange_bool_acq(mem, newval, oldval) \ @@ -63,13 +69,13 @@ volatile unsigned char __sparc32_atomic_lock int __aceb_ret; \ __typeof (*mem) __aceb_newval = (newval); \ \ - __sparc32_atomic_do_lock (); \ + __sparc32_atomic_do_lock (__aceb_memp); \ __aceb_ret = 0; \ if (*__aceb_memp == (oldval)) \ *__aceb_memp = __aceb_newval; \ else \ __aceb_ret = 1; \ - __sparc32_atomic_do_unlock (); \ + __sparc32_atomic_do_unlock (__aceb_memp); \ __aceb_ret; }) #endif /* bits/atomic.h */ diff --git a/sysdeps/sparc/sparc32/elf/configure b/sysdeps/sparc/sparc32/elf/configure index e5ff89c065..d4f9517959 100644 --- a/sysdeps/sparc/sparc32/elf/configure +++ b/sysdeps/sparc/sparc32/elf/configure @@ -29,7 +29,7 @@ baz: sethi %tgd_hi22(foo), %l1 add %o0, %l1, %l1, %tldo_add(bar) sethi %tie_hi22(foo), %l1 add %l1, %tie_lo10(foo), %l1 - ld %l7 + %l1, %l1, %tie_ld(foo) + ld [%l7 + %l1], %l1, %tie_ld(foo) add %g7, %l1, %l1, %tie_add(foo) sethi %tle_hix22(foo), %l1 xor %l1, %tle_lox10(foo), %l1 diff --git a/sysdeps/unix/sysv/linux/sparc/sys/user.h b/sysdeps/unix/sysv/linux/sparc/sys/user.h new file mode 100644 index 0000000000..2aad01b0ff --- /dev/null +++ b/sysdeps/unix/sysv/linux/sparc/sys/user.h @@ -0,0 +1,85 @@ +/* Copyright (C) 2003 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#ifndef _SYS_USER_H +#define _SYS_USER_H 1 + +struct sunos_regs +{ + unsigned int psr, pc, npc, y; + unsigned int regs[15]; +}; + +struct sunos_fpqueue +{ + unsigned int *addr; + unsigned int inst; +}; + +struct sunos_fp +{ + union + { + unsigned int regs[32]; + double reg_dbls[16]; + } fregs; + unsigned int fsr; + unsigned int flags; + unsigned int extra; + unsigned int fpq_count; + struct sunos_fpqueue fpq[16]; +}; + +struct sunos_fpu +{ + struct sunos_fp fpstatus; +}; + +/* The SunOS core file header layout. */ +struct user { + unsigned int magic; + unsigned int len; + struct sunos_regs regs; + struct + { + unsigned char a_dynamic :1; + unsigned char a_toolversion :7; + unsigned char a_machtype; + unsigned short a_info; + unsigned int a_text; + unsigned int a_data; + unsigned int a_bss; + unsigned int a_syms; + unsigned int a_entry; + unsigned int a_trsize; + unsigned int a_drsize; + } uexec; + int signal; + size_t u_tsize; + size_t u_dsize; + size_t u_ssize; + char u_comm[17]; + struct sunos_fpu fpu; + unsigned int sigcode; +}; + +#define NBPG 0x2000 +#define UPAGES 1 +#define SUNOS_CORE_MAGIC 0x080456 + +#endif