diff options
author | Jakub Jelinek <jakub@redhat.com> | 2007-07-12 18:26:36 +0000 |
---|---|---|
committer | Jakub Jelinek <jakub@redhat.com> | 2007-07-12 18:26:36 +0000 |
commit | 0ecb606cb6cf65de1d9fc8a919bceb4be476c602 (patch) | |
tree | 2ea1f8305970753e4a657acb2ccc15ca3eec8e2c /sysdeps/unix/sysv/linux/sparc/sparc64 | |
parent | 7d58530341304d403a6626d7f7a1913165fe2f32 (diff) | |
download | glibc-0ecb606cb6cf65de1d9fc8a919bceb4be476c602.tar glibc-0ecb606cb6cf65de1d9fc8a919bceb4be476c602.tar.gz glibc-0ecb606cb6cf65de1d9fc8a919bceb4be476c602.tar.bz2 glibc-0ecb606cb6cf65de1d9fc8a919bceb4be476c602.zip |
2.5-18.1
Diffstat (limited to 'sysdeps/unix/sysv/linux/sparc/sparc64')
21 files changed, 355 insertions, 322 deletions
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/Dist b/sysdeps/unix/sysv/linux/sparc/sparc64/Dist deleted file mode 100644 index 4ba3a60c2c..0000000000 --- a/sysdeps/unix/sysv/linux/sparc/sparc64/Dist +++ /dev/null @@ -1,7 +0,0 @@ -clone.S -dl-brk.S -kernel_stat.h -getcontext.S -setcontext.S -sizes.h -ucontext_i.h diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/brk.S b/sysdeps/unix/sysv/linux/sparc/sparc64/brk.S index 1fabd11f71..134ce789f7 100644 --- a/sysdeps/unix/sysv/linux/sparc/sparc64/brk.S +++ b/sysdeps/unix/sysv/linux/sparc/sparc64/brk.S @@ -37,8 +37,11 @@ __curbrk: .skip 8 #endif .text -ENTRY(__brk) +ENTRY (__brk) save %sp, -192, %sp + cfi_def_cfa_register(%fp) + cfi_window_save + cfi_register(%o7, %i7) #ifdef PIC 1: call 2f sethi %hi(_GLOBAL_OFFSET_TABLE_-(1b-.)), %l7 @@ -90,7 +93,6 @@ ENTRY(__brk) sub %g0, 1, %i0 jmpl %i7+8, %g0 restore - - .size __brk, .-__brk +END (__brk) weak_alias (__brk, brk) diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/clone.S b/sysdeps/unix/sysv/linux/sparc/sparc64/clone.S index a7c248b2e8..ebfce9e2c5 100644 --- a/sysdeps/unix/sysv/linux/sparc/sparc64/clone.S +++ b/sysdeps/unix/sysv/linux/sparc/sparc64/clone.S @@ -22,34 +22,52 @@ #include <asm/errno.h> #include <asm/unistd.h> +#include <tcb-offsets.h> +#include <sysdep.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 - .globl __clone - .type __clone,@function -__clone: +ENTRY (__clone) save %sp, -192, %sp + cfi_def_cfa_register(%fp) + cfi_window_save + cfi_register(%o7, %i7) /* 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 - ret - restore + nop + jmpl %i7 + 8, %g0 + restore %o0, %g0, %o0 99: #ifndef _LIBC_REENTRANT #ifdef PIC @@ -71,18 +89,33 @@ __clone: nop st %i0, [%o0] #endif - ret + jmpl %i7 + 8, %g0 restore %g0,-1,%o0 - .size __clone, .-__clone +END(__clone) .type __thread_start,@function __thread_start: + cfi_startproc +#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 + cfi_endproc + + .size __thread_start, .-__thread_start -weak_alias(__clone, clone) +weak_alias (__clone, clone) diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/dl-procinfo.c b/sysdeps/unix/sysv/linux/sparc/sparc64/dl-procinfo.c deleted file mode 100644 index 0a453a6811..0000000000 --- a/sysdeps/unix/sysv/linux/sparc/sparc64/dl-procinfo.c +++ /dev/null @@ -1,64 +0,0 @@ -/* Data for Linux/sparc64 version of processor capability information. - Copyright (C) 2002, 2003 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Jakub Jelinek <jakub@redhat.com>, 2002. - - 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. */ - -/* This information must be kept in sync with the _DL_HWCAP_COUNT - definition in procinfo.h. - - If anything should be added here check whether the size of each string - is still ok with the given array size. - - All the #ifdefs in the definitions ar equite irritating but - necessary if we want to avoid duplicating the information. There - are three different modes: - - - PROCINFO_DECL is defined. This means we are only interested in - declarations. - - - PROCINFO_DECL is not defined: - - + if SHARED is defined the file is included in an array - initializer. The .element = { ... } syntax is needed. - - + if SHARED is not defined a normal array initialization is - needed. - */ - -#ifndef PROCINFO_CLASS -#define PROCINFO_CLASS -#endif - -#if !defined PROCINFO_DECL && defined SHARED - ._dl_sparc64_cap_flags -#else -PROCINFO_CLASS const char _dl_sparc64_cap_flags[6][7] -#endif -#ifndef PROCINFO_DECL -= { - "flush", "stbar", "swap", "muldiv", "v9", "ultra3" - } -#endif -#if !defined SHARED || defined PROCINFO_DECL -; -#else -, -#endif - -#undef PROCINFO_DECL -#undef PROCINFO_CLASS diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/dl-procinfo.h b/sysdeps/unix/sysv/linux/sparc/sparc64/dl-procinfo.h deleted file mode 100644 index 3ce77a40e8..0000000000 --- a/sysdeps/unix/sysv/linux/sparc/sparc64/dl-procinfo.h +++ /dev/null @@ -1,76 +0,0 @@ -/* Linux/sparc64 version of processor capability information handling macros. - Copyright (C) 1999, 2000, 2001, 2002, 2004 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Jakub Jelinek <jj@ultra.linux.cz>, 1999. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ - -#ifndef _DL_PROCINFO_H -#define _DL_PROCINFO_H 1 - -#include <ldsodefs.h> - -#define _DL_HWCAP_COUNT 6 - -static inline int -__attribute__ ((unused)) -_dl_procinfo (int word) -{ - int i; - - _dl_printf ("AT_HWCAP: "); - - for (i = 0; i < _DL_HWCAP_COUNT; ++i) - if (word & (1 << i)) - _dl_printf (" %s", GLRO(dl_sparc64_cap_flags)[i]); - - _dl_printf ("\n"); - - return 0; -} - -static inline const char * -__attribute__ ((unused)) -_dl_hwcap_string (int idx) -{ - return GLRO(dl_sparc64_cap_flags)[idx]; -}; - - -static inline int -__attribute__ ((unused)) -_dl_string_hwcap (const char *str) -{ - int i; - for (i = 0; i < _DL_HWCAP_COUNT; i++) - { - if (strcmp (str, GLRO(dl_sparc64_cap_flags) [i]) == 0) - return i; - } - return -1; -}; - -#define HWCAP_IMPORTANT (HWCAP_SPARC_ULTRA3) - -/* There are no different platforms defined. */ -#define _dl_platform_string(idx) "" - -/* There're no platforms to filter out. */ -#define _DL_HWCAP_PLATFORM 0 - -#define _dl_string_platform(str) (-1) - -#endif /* dl-procinfo.h */ diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/fxstatat.c b/sysdeps/unix/sysv/linux/sparc/sparc64/fxstatat.c new file mode 100644 index 0000000000..db08af8e0f --- /dev/null +++ b/sysdeps/unix/sysv/linux/sparc/sparc64/fxstatat.c @@ -0,0 +1 @@ +#include "../../i386/fxstatat.c" diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/getcontext.S b/sysdeps/unix/sysv/linux/sparc/sparc64/getcontext.S index ea18a9ae4e..e6f5b55d6f 100644 --- a/sysdeps/unix/sysv/linux/sparc/sparc64/getcontext.S +++ b/sysdeps/unix/sysv/linux/sparc/sparc64/getcontext.S @@ -62,4 +62,4 @@ ENTRY(__getcontext) END(__getcontext) -weak_alias(__getcontext, getcontext) +weak_alias (__getcontext, getcontext) diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/kernel_stat.h b/sysdeps/unix/sysv/linux/sparc/sparc64/kernel_stat.h index 700dd127d0..a4e411d132 100644 --- a/sysdeps/unix/sysv/linux/sparc/sparc64/kernel_stat.h +++ b/sysdeps/unix/sysv/linux/sparc/sparc64/kernel_stat.h @@ -9,31 +9,39 @@ struct kernel_stat unsigned int st_gid; unsigned int st_rdev; long int st_size; - long int st_atime; - long int st_mtime; - long int st_ctime; + long int st_atime_sec; + long int st_mtime_sec; + long int st_ctime_sec; long int st_blksize; long int st_blocks; unsigned long int __unused1; unsigned long int __unused2; }; -#define _HAVE___UNUSED1 -#define _HAVE___UNUSED2 +/* Definition of `struct stat64' used in the kernel. */ +struct kernel_stat64 + { + unsigned long int st_dev; + unsigned long int st_ino; + unsigned long int st_nlink; + + unsigned int st_mode; + unsigned int st_uid; + unsigned int st_gid; + unsigned int __pad0; -#define _HAVE_STAT___UNUSED1 -#define _HAVE_STAT___UNUSED2 -#define _HAVE_STAT___UNUSED3 -#define _HAVE_STAT___UNUSED4 -#define _HAVE_STAT___UNUSED5 -#define _HAVE_STAT___PAD1 -#define _HAVE_STAT___PAD2 -#define _HAVE_STAT64___UNUSED1 -#define _HAVE_STAT64___UNUSED2 -#define _HAVE_STAT64___UNUSED3 -#define _HAVE_STAT64___UNUSED4 -#define _HAVE_STAT64___UNUSED5 -#define _HAVE_STAT64___PAD1 -#define _HAVE_STAT64___PAD2 + unsigned long int st_rdev; + long int st_size; + long int st_blksize; + long int st_blocks; + + unsigned long int st_atime_sec; + unsigned long int st_atime_nsec; + unsigned long int st_mtime_sec; + unsigned long int st_mtime_nsec; + unsigned long int st_ctime_sec; + unsigned long int st_ctime_nsec; + long int __unused[3]; + }; #define XSTAT_IS_XSTAT64 1 diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/longjmp.S b/sysdeps/unix/sysv/linux/sparc/sparc64/longjmp.S index 435bf99acb..88dc54e852 100644 --- a/sysdeps/unix/sysv/linux/sparc/sparc64/longjmp.S +++ b/sysdeps/unix/sysv/linux/sparc/sparc64/longjmp.S @@ -47,6 +47,6 @@ END(__libc_siglongjmp) strong_alias(__libc_siglongjmp, __longjmp) strong_alias(__libc_siglongjmp, __libc_longjmp) libc_hidden_def (__libc_longjmp) -weak_alias(__libc_siglongjmp, longjmp) -weak_alias(__libc_siglongjmp, _longjmp) -weak_alias(__libc_siglongjmp, siglongjmp) +weak_alias (__libc_siglongjmp, longjmp) +weak_alias (__libc_siglongjmp, _longjmp) +weak_alias (__libc_siglongjmp, siglongjmp) diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/lxstat.c b/sysdeps/unix/sysv/linux/sparc/sparc64/lxstat.c index 7637472dfc..7f1e98e433 100644 --- a/sysdeps/unix/sysv/linux/sparc/sparc64/lxstat.c +++ b/sysdeps/unix/sysv/linux/sparc/sparc64/lxstat.c @@ -1 +1 @@ -#include "../../lxstat.c" +#include "../../i386/lxstat.c" diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/pause.c b/sysdeps/unix/sysv/linux/sparc/sparc64/pause.c index 2ec5bd39ad..e399e7c7eb 100644 --- a/sysdeps/unix/sysv/linux/sparc/sparc64/pause.c +++ b/sysdeps/unix/sysv/linux/sparc/sparc64/pause.c @@ -1 +1,9 @@ +#include <errno.h> +#include <signal.h> +#include <unistd.h> +#include <sysdep-cancel.h> + +#define __sigprocmask(how, set, oset) \ + INLINE_SYSCALL (rt_sigprocmask, 4, how, set, oset, _NSIG / 8) + #include <sysdeps/posix/pause.c> diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/pipe.S b/sysdeps/unix/sysv/linux/sparc/sparc64/pipe.S index 5ccedff21a..14f244e628 100644 --- a/sysdeps/unix/sysv/linux/sparc/sparc64/pipe.S +++ b/sysdeps/unix/sysv/linux/sparc/sparc64/pipe.S @@ -19,18 +19,22 @@ #include <sysdep.h> -ENTRY (__libc_pipe) + .text + + .globl __syscall_error +ENTRY(__libc_pipe) mov %o0, %o2 /* Save PIPEDES. */ LOADSYSCALL(pipe) ta 0x6d - bcs,pn %xcc, __syscall_error_handler - nop - st %o0, [%o2] /* PIPEDES[0] = %o0; */ + bcc,pt %xcc, 1f + mov %o7, %g1 + call __syscall_error + mov %g1, %o7 +1: st %o0, [%o2] /* PIPEDES[0] = %o0; */ st %o1, [%o2 + 4] /* PIPEDES[1] = %o1; */ retl clr %o0 - SYSCALL_ERROR_HANDLER -PSEUDO_END (__libc_pipe) +END(__libc_pipe) weak_alias (__libc_pipe, __pipe) libc_hidden_def (__pipe) diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/setcontext.S b/sysdeps/unix/sysv/linux/sparc/sparc64/setcontext.S index 4e0bc96d22..90d47c18fa 100644 --- a/sysdeps/unix/sysv/linux/sparc/sparc64/setcontext.S +++ b/sysdeps/unix/sysv/linux/sparc/sparc64/setcontext.S @@ -24,12 +24,15 @@ .weak setcontext ENTRY(setcontext) - mov 1, %o1 + ba,pt %xcc, 1f + mov 1, %o1 + +END(setcontext) /* int __setcontext(ucontext_t *ctx, int restoremask); */ ENTRY(__setcontext) - ldx [%o0 + UC_SIGMASK], %o2 +1: ldx [%o0 + UC_SIGMASK], %o2 stx %o2, [%o0 + __UC_SIGMASK] ta 0x6f diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/setjmp.S b/sysdeps/unix/sysv/linux/sparc/sparc64/setjmp.S index 1a9359af5b..ab1690bb42 100644 --- a/sysdeps/unix/sysv/linux/sparc/sparc64/setjmp.S +++ b/sysdeps/unix/sysv/linux/sparc/sparc64/setjmp.S @@ -39,7 +39,8 @@ libc_hidden_def (_setjmp) /* int setjmp(jmp_buf) */ ENTRY(setjmp) - set 1, %o1 + ba,pt %xcc, __sigsetjmp_local + set 1, %o1 END(setjmp) /* int __sigsetjmp(jmp_buf, savemask) */ diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/sigaction.c b/sysdeps/unix/sysv/linux/sparc/sparc64/sigaction.c index 0a2d2c3dde..b5e35f4e40 100644 --- a/sysdeps/unix/sysv/linux/sparc/sparc64/sigaction.c +++ b/sysdeps/unix/sysv/linux/sparc/sparc64/sigaction.c @@ -1,5 +1,5 @@ /* POSIX.1 sigaction call for Linux/SPARC64. - Copyright (C) 1997,1998,1999,2000,2002,2003 Free Software Foundation, Inc. + Copyright (C) 1997-2000,2002,2003,2005 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Miguel de Icaza (miguel@nuclecu.unam.mx) and Jakub Jelinek (jj@ultra.linux.cz). @@ -65,6 +65,10 @@ __libc_sigaction (int sig, __const struct sigaction *act, } libc_hidden_def (__libc_sigaction) +#ifdef WRAPPER_INCLUDE +# include WRAPPER_INCLUDE +#endif + #ifndef LIBC_SIGACTION weak_alias (__libc_sigaction, __sigaction); libc_hidden_weak (__sigaction) diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/sigsuspend.c b/sysdeps/unix/sysv/linux/sparc/sparc64/sigsuspend.c deleted file mode 100644 index 1f06e3d534..0000000000 --- a/sysdeps/unix/sysv/linux/sparc/sparc64/sigsuspend.c +++ /dev/null @@ -1 +0,0 @@ -#include "../../ia64/sigsuspend.c" diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/socket.S b/sysdeps/unix/sysv/linux/sparc/sparc64/socket.S index 575416ff3f..353705b4ac 100644 --- a/sysdeps/unix/sysv/linux/sparc/sparc64/socket.S +++ b/sysdeps/unix/sysv/linux/sparc/sparc64/socket.S @@ -40,11 +40,15 @@ The .S files for the other calls just #define socket and #include this. */ #ifndef __socket -#define __socket P(__,socket) +# ifndef NO_WEAK_ALIAS +# define __socket P(__,socket) +# else +# define __socket socket +# endif #endif -.globl __socket -ENTRY (__socket) + .globl __syscall_error +ENTRY(__socket) /* Drop up to 6 arguments (recvfrom) into the memory allocated by the caller for varargs, since that's really what we have. */ @@ -73,14 +77,15 @@ ENTRY (__socket) LOADSYSCALL(socketcall) ta 0x6d - bcs,pn %xcc, __syscall_error_handler - nop - retl + bcc,pt %xcc, 1f + mov %o7, %g1 + call __syscall_error + mov %g1, %o7 +1: retl nop #if defined NEED_CANCELLATION && defined CENABLE .Lsocket_cancel: - cfi_startproc save %sp, -160, %sp cfi_def_cfa_register (%fp) cfi_window_save @@ -93,18 +98,22 @@ ENTRY (__socket) LOADSYSCALL(socketcall) ta 0x6d - bcs,pn %xcc, __syscall_error_handler2 + bcc,pt %xcc, 1f mov %o0, %l1 - CDISABLE + CDISABLE; + mov %l0, %o0; + call __syscall_error; + mov %l1, %o0; + ba,pt %xcc, 2f + mov -1, %l1; +1: CDISABLE mov %l0, %o0 - jmpl %i7 + 8, %g0 +2: jmpl %i7 + 8, %g0 restore %g0, %l1, %o0 - cfi_endproc - SYSCALL_ERROR_HANDLER2 #endif - SYSCALL_ERROR_HANDLER - -END (__socket) +END(__socket) +#ifndef NO_WEAK_ALIAS weak_alias (__socket, socket) +#endif diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/syscall.S b/sysdeps/unix/sysv/linux/sparc/sparc64/syscall.S index 27bd086206..27487d8ed9 100644 --- a/sysdeps/unix/sysv/linux/sparc/sparc64/syscall.S +++ b/sysdeps/unix/sysv/linux/sparc/sparc64/syscall.S @@ -19,8 +19,8 @@ #include <sysdep.h> .text -ENTRY (syscall) - + .globl __syscall_error +ENTRY(syscall) mov %o0,%g1 mov %o1,%o0 mov %o2,%o1 @@ -30,11 +30,10 @@ ENTRY (syscall) ta 0x6d - bcs,pn %xcc,__syscall_error_handler - nop - retl + bcc,pt %xcc, 1f + mov %o7, %g1 + call __syscall_error + mov %g1, %o7 +1: retl nop - - SYSCALL_ERROR_HANDLER - -PSEUDO_END (syscall) +END(syscall) diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/sysdep.h b/sysdeps/unix/sysv/linux/sparc/sparc64/sysdep.h index 3c6492aeca..f156f9241a 100644 --- a/sysdeps/unix/sysv/linux/sparc/sparc64/sysdep.h +++ b/sysdeps/unix/sysv/linux/sparc/sparc64/sysdep.h @@ -1,4 +1,5 @@ -/* Copyright (C) 1997, 2000, 2002, 2003, 2004 Free Software Foundation, Inc. +/* Copyright (C) 1997, 2000, 2002, 2003, 2004, 2006 + Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Richard Henderson <richard@gnu.ai.mit.edu>, 1997. @@ -25,6 +26,7 @@ #ifdef IS_IN_rtld # include <dl-sysdep.h> /* Defines RTLD_PRIVATE_ERRNO. */ #endif +#include <tls.h> #undef SYS_ify #define SYS_ify(syscall_name) __NR_##syscall_name @@ -47,99 +49,52 @@ #undef PSEUDO #undef PSEUDO_NOERRNO #undef PSEUDO_ERRVAL -#undef ENTRY - -#define ENTRY(name) \ - .global C_SYMBOL_NAME(name); \ - .align 2; \ - C_LABEL(name); \ - .type name,@function; - -#ifdef LINKER_HANDLES_R_SPARC_WDISP22 -/* Unfortunately, we cannot do this yet. Linker doesn't seem to - handle R_SPARC_WDISP22 against non-STB_LOCAL symbols properly . */ -# define SYSCALL_ERROR_HANDLER_ENTRY(handler) \ - .section .gnu.linkonce.t.handler,"ax",@progbits; \ - .globl handler; \ - .hidden handler; \ - .type handler,@function; \ -handler: -#else -# define SYSCALL_ERROR_HANDLER_ENTRY(handler) \ - .subsection 3; \ -handler: -#endif - -#if RTLD_PRIVATE_ERRNO -# 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 %hi(_GLOBAL_OFFSET_TABLE_-4), %l7; \ - call __sparc64.get_pic.l7; \ - add %l7, %lo(_GLOBAL_OFFSET_TABLE_+4), %l7; \ - ldx [%l7 + rtld_errno], %l0; \ - st %i0, [%l0]; \ - jmpl %i7+8, %g0; \ - restore %g0, -1, %o0; \ - .previous; -#else -# define SYSCALL_ERROR_HANDLER \ -SYSCALL_ERROR_HANDLER_ENTRY(__syscall_error_handler) \ - .global __errno_location; \ - .type __errno_location,@function; \ - save %sp, -192, %sp; \ - call __errno_location; \ - nop; \ - st %i0, [%o0]; \ - jmpl %i7+8, %g0; \ - restore %g0, -1, %o0; \ - .previous; -#endif - -#define PSEUDO(name, syscall_name, args) \ - .text; \ - ENTRY(name); \ - LOADSYSCALL(syscall_name); \ - ta 0x6d; \ - bcs,pn %xcc, __syscall_error_handler; \ - nop; \ - SYSCALL_ERROR_HANDLER - -#define PSEUDO_NOERRNO(name, syscall_name, args) \ - .text; \ - ENTRY(name); \ - LOADSYSCALL(syscall_name); \ - ta 0x6d - -#define PSEUDO_ERRVAL(name, syscall_name, args) \ - .text; \ - ENTRY(name); \ - LOADSYSCALL(syscall_name); \ - ta 0x6d - #undef PSEUDO_END -#define PSEUDO_END(name) \ - .size name,.-name - -#undef PSEUDO_END_NOERRNO -#define PSEUDO_END_NOERRNO(name) \ - .size name,.-name +#undef ENTRY +#undef END -#undef PSEUDO_END_ERRVAL -#define PSEUDO_END_ERRVAL(name) \ - .size name,.-name +#define ENTRY(name) \ + .align 4; \ + .global C_SYMBOL_NAME(name); \ + .type name, @function; \ +C_LABEL(name) \ + cfi_startproc; + +#define END(name) \ + cfi_endproc; \ + .size name, . - name + + /* If the offset to __syscall_error fits into a signed 22-bit + * immediate branch offset, the linker will relax the call into + * a normal branch. + */ +#define PSEUDO(name, syscall_name, args) \ + .text; \ + .globl __syscall_error; \ +ENTRY(name); \ + LOADSYSCALL(syscall_name); \ + ta 0x6d; \ + bcc,pt %xcc, 1f; \ + mov %o7, %g1; \ + call __syscall_error; \ + mov %g1, %o7; \ +1: + +#define PSEUDO_NOERRNO(name, syscall_name, args)\ + .text; \ +ENTRY(name); \ + LOADSYSCALL(syscall_name); \ + ta 0x6d; + +#define PSEUDO_ERRVAL(name, syscall_name, args) \ + .text; \ +ENTRY(name); \ + LOADSYSCALL(syscall_name); \ + ta 0x6d; + +#define PSEUDO_END(name) \ + END(name) -#undef END -#define END(name) \ - .size name,.-name /* Careful here! This "ret" define can interfere; use jmpl if unsure. */ #define ret retl; nop @@ -197,4 +152,24 @@ SYSCALL_ERROR_HANDLER_ENTRY(__syscall_error_handler) \ register windows. So if you poke stack memory directly you add this. */ #define STACK_BIAS 2047 +/* Pointer mangling support. */ +#if defined NOT_IN_libc && defined IS_IN_rtld +/* We cannot use the thread descriptor because in ld.so we use setjmp + earlier than the descriptor is initialized. */ +#else +# ifdef __ASSEMBLER__ +# define PTR_MANGLE(dreg, reg, tmpreg) \ + ldx [%g7 + POINTER_GUARD], tmpreg; \ + xor reg, tmpreg, dreg +# define PTR_DEMANGLE(dreg, reg, tmpreg) PTR_MANGLE (dreg, reg, tmpreg) +# define PTR_MANGLE2(dreg, reg, tmpreg) \ + xor reg, tmpreg, dreg +# define PTR_DEMANGLE2(dreg, reg, tmpreg) PTR_MANGLE2 (dreg, reg, tmpreg) +# else +# define PTR_MANGLE(var) \ + (var) = (__typeof (var)) ((uintptr_t) (var) ^ THREAD_GET_POINTER_GUARD ()) +# define PTR_DEMANGLE(var) PTR_MANGLE (var) +# endif +#endif + #endif /* linux/sparc64/sysdep.h */ diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/xstat.c b/sysdeps/unix/sysv/linux/sparc/sparc64/xstat.c index 27d700b133..9f4c02c78b 100644 --- a/sysdeps/unix/sysv/linux/sparc/sparc64/xstat.c +++ b/sysdeps/unix/sysv/linux/sparc/sparc64/xstat.c @@ -1 +1,8 @@ -#include "../../xstat.c" +#include "../../i386/xstat.c" + +#ifdef __NR_stat64 +# if __ASSUME_STAT64_SYSCALL == 0 +/* The variable is shared between all wrappers around *stat{,64} calls. */ +int __have_no_stat64; +# endif +#endif diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/xstatconv.c b/sysdeps/unix/sysv/linux/sparc/sparc64/xstatconv.c new file mode 100644 index 0000000000..d3f49eea43 --- /dev/null +++ b/sysdeps/unix/sysv/linux/sparc/sparc64/xstatconv.c @@ -0,0 +1,127 @@ +/* Convert between the kernel's `struct stat' format, and libc's. + Copyright (C) 1991, 1995, 1996, 1997, 2000, 2002, 2003, 2006 + 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 <assert.h> +#include <errno.h> +#include <sys/stat.h> +#include <kernel_stat.h> +#include <string.h> +#include <kernel-features.h> + +int +__xstat_conv (int vers, struct kernel_stat *kbuf, void *ubuf) +{ + switch (vers) + { + case _STAT_VER_KERNEL: + /* Nothing to do. The struct is in the form the kernel expects. + We should have short-circuted before we got here, but for + completeness... */ + *(struct kernel_stat *) ubuf = *kbuf; + break; + + case _STAT_VER_LINUX: + { + struct stat *buf = ubuf; + + /* Convert to current kernel version of `struct stat'. */ + buf->st_dev = kbuf->st_dev; + buf->__pad1 = 0; + buf->st_ino = kbuf->st_ino; + buf->st_mode = kbuf->st_mode; + buf->st_nlink = kbuf->st_nlink; + buf->st_uid = kbuf->st_uid; + buf->st_gid = kbuf->st_gid; + buf->st_rdev = kbuf->st_rdev; + buf->__pad2 = 0; + buf->st_size = kbuf->st_size; + buf->st_blksize = kbuf->st_blksize; + buf->st_blocks = kbuf->st_blocks; + buf->st_atim.tv_sec = kbuf->st_atime_sec; + buf->st_atim.tv_nsec = 0; + buf->st_mtim.tv_sec = kbuf->st_mtime_sec; + buf->st_mtim.tv_nsec = 0; + buf->st_ctim.tv_sec = kbuf->st_ctime_sec; + buf->st_ctim.tv_nsec = 0; + buf->__unused4 = 0; + buf->__unused5 = 0; + } + break; + + default: + __set_errno (EINVAL); + return -1; + } + + return 0; +} + +int +__xstat32_conv (int vers, struct stat64 *sbuf, struct stat *buf) +{ + struct kernel_stat64 *kbuf; + + /* *stat64 syscalls on sparc64 really fill in struct kernel_stat64, + rather than struct stat64. But it is the same size as + struct kernel_stat64, so use this hack so that we can reuse + i386 {,f,l}xstat{,at}.c routines. */ + __asm ("" : "=r" (kbuf) : "0" (sbuf)); + assert (sizeof (struct stat) == sizeof (struct stat64)); + assert (sizeof (struct stat64) >= sizeof (struct kernel_stat64)); + + switch (vers) + { + case _STAT_VER_LINUX: + { + /* Convert current kernel version of `struct stat64' to + `struct stat'. */ + buf->st_dev = kbuf->st_dev; + buf->__pad1 = 0; + buf->st_ino = kbuf->st_ino; + buf->st_mode = kbuf->st_mode; + buf->st_nlink = kbuf->st_nlink; + buf->st_uid = kbuf->st_uid; + buf->st_gid = kbuf->st_gid; + buf->st_rdev = kbuf->st_rdev; + buf->__pad2 = 0; + buf->st_size = kbuf->st_size; + buf->st_blksize = kbuf->st_blksize; + buf->st_blocks = kbuf->st_blocks; + buf->st_atim.tv_sec = kbuf->st_atime_sec; + buf->st_atim.tv_nsec = kbuf->st_atime_nsec; + buf->st_mtim.tv_sec = kbuf->st_mtime_sec; + buf->st_mtim.tv_nsec = kbuf->st_mtime_nsec; + buf->st_ctim.tv_sec = kbuf->st_ctime_sec; + buf->st_ctim.tv_nsec = kbuf->st_ctime_nsec; + buf->__unused4 = 0; + buf->__unused5 = 0; + } + break; + + /* If struct stat64 is different from struct stat then + _STAT_VER_KERNEL does not make sense. */ + case _STAT_VER_KERNEL: + default: + __set_errno (EINVAL); + return -1; + } + + return 0; +} |