]> git.ipfire.org Git - thirdparty/glibc.git/blobdiff - sysdeps/unix/sysv/linux/sh/sysdep.h
Prefer https to http for gnu.org and fsf.org URLs
[thirdparty/glibc.git] / sysdeps / unix / sysv / linux / sh / sysdep.h
index cb36ec76636921ee3d4ef6c234fc57ac150fbb02..52e77c9913cfdc6c8b366b1f7949546649d23e3b 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 1992, 1993, 1995, 1996, 1997, 1998, 1999, 2000, 2002, 2003 Free Software Foundation, Inc.
+/* Copyright (C) 1992-2019 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper, <drepper@gnu.ai.mit.edu>, August 1995.
    Changed by Kaz Kojima, <kkojima@rr.iij4u.or.jp>.
    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.  */
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
 
 #ifndef _LINUX_SH_SYSDEP_H
 #define _LINUX_SH_SYSDEP_H 1
 
 /* There is some commonality.  */
+#include <sysdeps/unix/sysv/linux/sysdep.h>
 #include <sysdeps/unix/sh/sysdep.h>
+#include <tls.h>
 
 /* For Linux we can use the system call table in the header file
        /usr/include/asm/unistd.h
 # if RTLD_PRIVATE_ERRNO
 #  define SYSCALL_ERROR_HANDLER        \
        neg r0,r1; \
+       mov r12,r2; \
+       cfi_register (r12, r2); \
        mov.l 0f,r12; \
        mova 0f,r0; \
        add r0,r12; \
        mov.l 1f,r0; \
-       mov.l r1,@(r0,r12)
+       mov.l r1,@(r0,r12); \
+       mov r2,r12; \
+       cfi_restore (r12); \
        bra .Lpseudo_end; \
         mov _IMM1,r0; \
        .align 2; \
      0: .long _GLOBAL_OFFSET_TABLE_; \
-     1: .long errno@GOTOFF
+     1: .long rtld_errno@GOTOFF
 
 # elif defined _LIBC_REENTRANT
 
-#  if USE___THREAD
-#   ifndef NOT_IN_libc
-#    define SYSCALL_ERROR_ERRNO __libc_errno
-#   else
-#    define SYSCALL_ERROR_ERRNO errno
-#   endif
-#   define SYSCALL_ERROR_HANDLER \
+#  if IS_IN (libc)
+#   define SYSCALL_ERROR_ERRNO __libc_errno
+#  else
+#   define SYSCALL_ERROR_ERRNO errno
+#  endif
+#  define SYSCALL_ERROR_HANDLER \
        neg r0,r1; \
        mov r12,r2; \
+       cfi_register (r12, r2); \
        mov.l 0f,r12; \
        mova 0f,r0; \
        add r0,r12; \
        stc gbr, r4; \
        mov.l @(r0,r12),r0; \
        mov r2,r12; \
+       cfi_restore (r12); \
        add r4,r0; \
        mov.l r1,@r0; \
        bra .Lpseudo_end; \
        .align 2; \
      0: .long _GLOBAL_OFFSET_TABLE_; \
      1: .long SYSCALL_ERROR_ERRNO@GOTTPOFF
-#  else
-#   define SYSCALL_ERROR_HANDLER \
-       neg r0,r1; \
-       mov.l r14,@-r15; \
-       mov.l r12,@-r15; \
-       mov.l r1,@-r15; \
-       mov.l 0f,r12; \
-       mova 0f,r0; \
-       add r0,r12; \
-       sts.l pr,@-r15; \
-       mov r15,r14; \
-       mov.l 1f,r1; \
-       bsrf r1; \
-         nop; \
-     2: mov r14,r15; \
-       lds.l @r15+,pr; \
-       mov.l @r15+,r1; \
-       mov.l r1,@r0; \
-       mov.l @r15+,r12; \
-       mov.l @r15+,r14; \
-       bra .Lpseudo_end; \
-        mov _IMM1,r0; \
-       .align 2; \
-     0: .long _GLOBAL_OFFSET_TABLE_; \
-     1: .long PLTJMP(C_SYMBOL_NAME(__errno_location))-(2b+2-.)
-/* A quick note: it is assumed that the call to `__errno_location' does
-   not modify the stack!  */
-#  endif
 # else
 /* Store (-r0) into errno through the GOT.  */
 #  define SYSCALL_ERROR_HANDLER                                                      \
        neg r0,r1; \
        mov r12,r2; \
+       cfi_register (r12, r2); \
        mov.l 0f,r12; \
        mova 0f,r0; \
        add r0,r12; \
        mov.l 1f,r0; \
        mov.l @(r0,r12),r0; \
        mov r2,r12; \
+       cfi_restore (r12); \
        mov.l r1,@r0; \
        bra .Lpseudo_end; \
         mov _IMM1,r0; \
        , "r" (r4), "r" (r5), "r" (r6), "r" (r7), "0" (r0), "r" (r1), "r" (r2)
 
 #define SUBSTITUTE_ARGS_0()
-#define SUBSTITUTE_ARGS_1(arg1)                                        \
-       register long r4 asm ("%r4") = (long)(arg1)
-#define SUBSTITUTE_ARGS_2(arg1, arg2)                          \
-       register long r4 asm ("%r4") = (long)(arg1);            \
-       register long r5 asm ("%r5") = (long)(arg2)
-#define SUBSTITUTE_ARGS_3(arg1, arg2, arg3)                    \
-       register long r4 asm ("%r4") = (long)(arg1);            \
-       register long r5 asm ("%r5") = (long)(arg2);            \
-       register long r6 asm ("%r6") = (long)(arg3)
-#define SUBSTITUTE_ARGS_4(arg1, arg2, arg3, arg4)              \
-       register long r4 asm ("%r4") = (long)(arg1);            \
-       register long r5 asm ("%r5") = (long)(arg2);            \
-       register long r6 asm ("%r6") = (long)(arg3);            \
-       register long r7 asm ("%r7") = (long)(arg4)
-#define SUBSTITUTE_ARGS_5(arg1, arg2, arg3, arg4, arg5)        \
-       register long r4 asm ("%r4") = (long)(arg1);            \
-       register long r5 asm ("%r5") = (long)(arg2);            \
-       register long r6 asm ("%r6") = (long)(arg3);            \
-       register long r7 asm ("%r7") = (long)(arg4);            \
-       register long r0 asm ("%r0") = (long)(arg5)
-#define SUBSTITUTE_ARGS_6(arg1, arg2, arg3, arg4, arg5, arg6)          \
-       register long r4 asm ("%r4") = (long)(arg1);                    \
-       register long r5 asm ("%r5") = (long)(arg2);                    \
-       register long r6 asm ("%r6") = (long)(arg3);                    \
-       register long r7 asm ("%r7") = (long)(arg4);                    \
-       register long r0 asm ("%r0") = (long)(arg5);                    \
-       register long r1 asm ("%r1") = (long)(arg6)
-#define SUBSTITUTE_ARGS_7(arg1, arg2, arg3, arg4, arg5, arg6, arg7)    \
-       register long r4 asm ("%r4") = (long)(arg1);                    \
-       register long r5 asm ("%r5") = (long)(arg2);                    \
-       register long r6 asm ("%r6") = (long)(arg3);                    \
-       register long r7 asm ("%r7") = (long)(arg4);                    \
-       register long r0 asm ("%r0") = (long)(arg5)                     \
-       register long r1 asm ("%r1") = (long)(arg6);                    \
-       register long r2 asm ("%r2") = (long)(arg7)
+#define SUBSTITUTE_ARGS_1(arg1) \
+       long int _arg1 = (long int) (arg1);                                   \
+       register long int r4 asm ("%r4") = (long int) (_arg1)
+#define SUBSTITUTE_ARGS_2(arg1, arg2) \
+       long int _arg1 = (long int) (arg1);                                   \
+       long int _arg2 = (long int) (arg2);                                   \
+       register long int r4 asm ("%r4") = (long int) (_arg1);                \
+       register long int r5 asm ("%r5") = (long int) (_arg2)
+#define SUBSTITUTE_ARGS_3(arg1, arg2, arg3) \
+       long int _arg1 = (long int) (arg1);                                   \
+       long int _arg2 = (long int) (arg2);                                   \
+       long int _arg3 = (long int) (arg3);                                   \
+       register long int r4 asm ("%r4") = (long int) (_arg1);                \
+       register long int r5 asm ("%r5") = (long int) (_arg2);                \
+       register long int r6 asm ("%r6") = (long int) (_arg3)
+#define SUBSTITUTE_ARGS_4(arg1, arg2, arg3, arg4) \
+       long int _arg1 = (long int) (arg1);                                   \
+       long int _arg2 = (long int) (arg2);                                   \
+       long int _arg3 = (long int) (arg3);                                   \
+       long int _arg4 = (long int) (arg4);                                   \
+       register long int r4 asm ("%r4") = (long int) (_arg1);                \
+       register long int r5 asm ("%r5") = (long int) (_arg2);                \
+       register long int r6 asm ("%r6") = (long int) (_arg3);                \
+       register long int r7 asm ("%r7") = (long int) (_arg4)
+#define SUBSTITUTE_ARGS_5(arg1, arg2, arg3, arg4, arg5) \
+       long int _arg1 = (long int) (arg1);                                   \
+       long int _arg2 = (long int) (arg2);                                   \
+       long int _arg3 = (long int) (arg3);                                   \
+       long int _arg4 = (long int) (arg4);                                   \
+       long int _arg5 = (long int) (arg5);                                   \
+       register long int r4 asm ("%r4") = (long int) (_arg1);                \
+       register long int r5 asm ("%r5") = (long int) (_arg2);                \
+       register long int r6 asm ("%r6") = (long int) (_arg3);                \
+       register long int r7 asm ("%r7") = (long int) (_arg4);                \
+       register long int r0 asm ("%r0") = (long int) (_arg5)
+#define SUBSTITUTE_ARGS_6(arg1, arg2, arg3, arg4, arg5, arg6) \
+       long int _arg1 = (long int) (arg1);                                   \
+       long int _arg2 = (long int) (arg2);                                   \
+       long int _arg3 = (long int) (arg3);                                   \
+       long int _arg4 = (long int) (arg4);                                   \
+       long int _arg5 = (long int) (arg5);                                   \
+       long int _arg6 = (long int) (arg6);                                   \
+       register long int r4 asm ("%r4") = (long int)(_arg1);                 \
+       register long int r5 asm ("%r5") = (long int) (_arg2);                \
+       register long int r6 asm ("%r6") = (long int) (_arg3);                \
+       register long int r7 asm ("%r7") = (long int) (_arg4);                \
+       register long int r0 asm ("%r0") = (long int) (_arg5);                \
+       register long int r1 asm ("%r1") = (long int) (_arg6)
+#define SUBSTITUTE_ARGS_7(arg1, arg2, arg3, arg4, arg5, arg6, arg7) \
+       long int _arg1 = (long int) (arg1);                                   \
+       long int _arg2 = (long int) (arg2);                                   \
+       long int _arg3 = (long int) (arg3);                                   \
+       long int _arg4 = (long int) (arg4);                                   \
+       long int _arg5 = (long int) (arg5);                                   \
+       long int _arg6 = (long int) (arg6);                                   \
+       long int _arg7 = (long int) (arg7);                                   \
+       register long int r4 asm ("%r4") = (long int) (_arg1);                \
+       register long int r5 asm ("%r5") = (long int) (_arg2);                \
+       register long int r6 asm ("%r6") = (long int) (_arg3);                \
+       register long int r7 asm ("%r7") = (long int) (_arg4);                \
+       register long int r0 asm ("%r0") = (long int) (_arg5);                \
+       register long int r1 asm ("%r1") = (long int) (_arg6);                \
+       register long int r2 asm ("%r2") = (long int) (_arg7)
 
 #undef INLINE_SYSCALL
 #define INLINE_SYSCALL(name, nr, args...) \
     unsigned int resultvar = INTERNAL_SYSCALL (name, , nr, args);             \
     if (__builtin_expect (INTERNAL_SYSCALL_ERROR_P (resultvar, ), 0))         \
       {                                                                       \
-        __set_errno (INTERNAL_SYSCALL_ERRNO (resultvar, ));                   \
-        resultvar = 0xffffffff;                                               \
+       __set_errno (INTERNAL_SYSCALL_ERRNO (resultvar, ));                   \
+       resultvar = 0xffffffff;                                               \
       }                                                                       \
     (int) resultvar; })
 
 #undef INTERNAL_SYSCALL
 #define INTERNAL_SYSCALL(name, err, nr, args...) \
-  ({                                                           \
-    unsigned long resultvar;                                   \
-    register long r3 asm ("%r3") = SYS_ify (name);             \
-    SUBSTITUTE_ARGS_##nr(args);                                        \
-                                                               \
-    asm volatile (SYSCALL_INST_STR##nr SYSCALL_INST_PAD                \
-                 : "=z" (resultvar)                            \
-                 : "r" (r3) ASMFMT_##nr                        \
-                 : "memory");                                  \
-                                                               \
+  ({                                                                         \
+    unsigned long int resultvar;                                             \
+    register long int r3 asm ("%r3") = SYS_ify (name);                       \
+    SUBSTITUTE_ARGS_##nr(args);                                                      \
+                                                                             \
+    asm volatile (SYSCALL_INST_STR##nr SYSCALL_INST_PAD                              \
+                 : "=z" (resultvar)                                          \
+                 : "r" (r3) ASMFMT_##nr                                      \
+                 : "memory", "t");                                           \
+                                                                             \
+    (int) resultvar; })
+
+/* The _NCS variant allows non-constant syscall numbers.  */
+#define INTERNAL_SYSCALL_NCS(name, err, nr, args...) \
+  ({                                                                         \
+    unsigned long int resultvar;                                             \
+    register long int r3 asm ("%r3") = (name);                               \
+    SUBSTITUTE_ARGS_##nr(args);                                                      \
+                                                                             \
+    asm volatile (SYSCALL_INST_STR##nr SYSCALL_INST_PAD                              \
+                 : "=z" (resultvar)                                          \
+                 : "r" (r3) ASMFMT_##nr                                      \
+                 : "memory", "t");                                           \
+                                                                             \
     (int) resultvar; })
 
 #undef INTERNAL_SYSCALL_DECL
 
 #endif /* __ASSEMBLER__ */
 
+/* Pointer mangling support.  */
+#if IS_IN (rtld)
+/* We cannot use the thread descriptor because in ld.so we use setjmp
+   earlier than the descriptor is initialized.  Using a global variable
+   is too complicated here since we have no PC-relative addressing mode.  */
+#else
+# ifdef __ASSEMBLER__
+#  define PTR_MANGLE(reg, tmp) \
+     stc gbr,tmp; mov.l @(POINTER_GUARD,tmp),tmp; xor tmp,reg
+#  define PTR_MANGLE2(reg, tmp)        xor tmp,reg
+#  define PTR_DEMANGLE(reg, tmp)       PTR_MANGLE (reg, tmp)
+#  define PTR_DEMANGLE2(reg, tmp)      PTR_MANGLE2 (reg, tmp)
+# else
+#  define PTR_MANGLE(var) \
+     (var) = (void *) ((uintptr_t) (var) ^ THREAD_GET_POINTER_GUARD ())
+#  define PTR_DEMANGLE(var)    PTR_MANGLE (var)
+# endif
+#endif
+
 #endif /* linux/sh/sysdep.h */