about summary refs log tree commit diff
path: root/sysdeps/unix/sysv/linux/sh/sysdep.h
diff options
context:
space:
mode:
Diffstat (limited to 'sysdeps/unix/sysv/linux/sh/sysdep.h')
-rw-r--r--sysdeps/unix/sysv/linux/sh/sysdep.h35
1 files changed, 32 insertions, 3 deletions
diff --git a/sysdeps/unix/sysv/linux/sh/sysdep.h b/sysdeps/unix/sysv/linux/sh/sysdep.h
index d56ec454f9..f0be37edc8 100644
--- a/sysdeps/unix/sysv/linux/sh/sysdep.h
+++ b/sysdeps/unix/sysv/linux/sh/sysdep.h
@@ -1,5 +1,5 @@
-/* Copyright (C) 1992,1993,1995,1996,1997,1998,1999,2000,2002,2003,2004
-	Free Software Foundation, Inc.
+/* Copyright (C) 1992,1993,1995,1996,1997,1998,1999,2000,2002,2003,2004,
+   2005,2006	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>.
@@ -24,6 +24,7 @@
 
 /* There is some commonality.  */
 #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
@@ -104,7 +105,7 @@
 	mova 0f,r0; \
 	add r0,r12; \
 	mov.l 1f,r0; \
-	mov.l r1,@(r0,r12)
+	mov.l r1,@(r0,r12); \
 	bra .Lpseudo_end; \
 	 mov _IMM1,r0; \
 	.align 2; \
@@ -140,13 +141,22 @@
 #   define SYSCALL_ERROR_HANDLER \
 	neg r0,r1; \
 	mov.l r14,@-r15; \
+	cfi_adjust_cfa_offset (4); \
+	cfi_rel_offset (r14, 0); \
 	mov.l r12,@-r15; \
+	cfi_adjust_cfa_offset (4); \
+	cfi_rel_offset (r12, 0); \
 	mov.l r1,@-r15; \
+	cfi_adjust_cfa_offset (4); \
+	cfi_rel_offset (r1, 0); \
 	mov.l 0f,r12; \
 	mova 0f,r0; \
 	add r0,r12; \
 	sts.l pr,@-r15; \
+	cfi_adjust_cfa_offset (4); \
+	cfi_rel_offset (pr, 0); \
 	mov r15,r14; \
+	cfi_def_cfa_register (r14); \
 	mov.l 1f,r1; \
 	bsrf r1; \
          nop; \
@@ -359,4 +369,23 @@
 
 #endif	/* __ASSEMBLER__ */
 
+/* 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.  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 */