[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [microblaze-uclinux] [patch] errno corruption



Hi folks,

OK, attached is a slight tweak on Yashi's patch.

Differences are

(1) added "cc" and "r3" to generic clobbers set as per Paul's 
recommendation.
(2) added "r5",... to clobbers list for each syscallN as required.
(3) removed lingering __r5 register asm("r5") from syscall2

I think that's about it.  Generated assembly seems unchanged, but should 
be safer with these clobbers.

Yashi, would you mind testing this out, see if it works ok at your end, 
esp. with different optimisation level in uClibc?

Cheers,

John
--- /opt/src/uClinux-2.4.x/include/asm-microblaze/unistd.h	2004-03-16 04:31:32.000000000 +1000
+++ unistd.h	2004-03-19 15:26:08.000000000 +1000
@@ -256,133 +256,157 @@
 
 #define SYSCALL_ENTRY_POINT C_SYMBOL_NAME(syscall_entry)
 
-/* Registers clobbered by a syscall.  */
-#define SYSCALL_CLOBBERS	"r4", "r11", "r17", SYSCALL_NUM
+/*
+ * Registers clobbered by a syscall.
+ * Since we are using brach to implement syscall,
+ * all volatile registers, except r5-r10, must be in the clobbered list.
+ * r5-r10 should be in input list.
+ */
+#define SYSCALL_CLOBBERS	"cc", "r3", "r4", "r11", "r12", "r17"
 
-#define __syscall_return(type, res)					      \
-  do {									      \
-	  /* user-visible error numbers are in the range -1 - -124:	      \
-	     see <asm-microblaze/errno.h> */					      \
-	  if ((unsigned long)(res) >= (unsigned long)(-125)) {		      \
-		  /* mb-gcc bug work around.				      \
-		     it does't seem to preserve r3 before calling	      \
-		     __errno_location() -yashi Mar 15, 2004 */		      \
-		  unsigned long tmp = res;				      \
-		  errno = -(tmp);					      \
-		  res = -1;						      \
-	  }								      \
-	  return (type) (res);						      \
-  } while (0)
-
-#define _syscall0(type, name)						      \
-type name (void)							      \
-{									      \
-  register unsigned long __syscall __asm__ (SYSCALL_NUM) = __NR_##name;	      \
-  register unsigned long __ret __asm__ (SYSCALL_RET);			      \
-  __asm__ __volatile__ ("bralid r17, 0x8; nop"			      \
-			: "=r" (__ret)					      \
-			: "r" (__syscall)				      \
-			: SYSCALL_CLOBBERS);				      \
-  __syscall_return (type, __ret);					      \
-}
-
-#define _syscall1(type, name, atype, a)					      \
-type name (atype a)							      \
-{									      \
-  register atype __a __asm__ (SYSCALL_ARG0) = a;			      \
-  register unsigned long __syscall __asm__ (SYSCALL_NUM) = __NR_##name;	      \
-  register unsigned long __ret __asm__ (SYSCALL_RET);			      \
-  __asm__ __volatile__ ("bralid r17, 0x8; nop;"			      \
-			: "=r" (__ret)					      \
-			: "r" (__syscall), "r" (__a)			      \
-			: SYSCALL_CLOBBERS);				      \
-  __syscall_return (type, __ret);					      \
-}
-
-#define _syscall2(type, name, atype, a, btype, b)			      \
-type name (atype a, btype b)						      \
-{									      \
-  register atype __a __asm__ (SYSCALL_ARG0) = a;			      \
-  register btype __b __asm__ (SYSCALL_ARG1) = b;			      \
-  register unsigned long __syscall __asm__ (SYSCALL_NUM) = __NR_##name;	      \
-  register unsigned long __ret __asm__ (SYSCALL_RET);			      \
-  __asm__ __volatile__ ("bralid r17, 0x8; nop;"			      \
-			: "=r" (__ret)					      \
-			: "r" (__syscall), "r" (__a), "r" (__b)		      \
-			: SYSCALL_CLOBBERS);				      \
-  __syscall_return (type, __ret);					      \
-}
-
-#define _syscall3(type, name, atype, a, btype, b, ctype, c)		      \
-type name (atype a, btype b, ctype c)					      \
-{									      \
-  register atype __a __asm__ (SYSCALL_ARG0) = a;			      \
-  register btype __b __asm__ (SYSCALL_ARG1) = b;			      \
-  register ctype __c __asm__ (SYSCALL_ARG2) = c;			      \
-  register unsigned long __syscall __asm__ (SYSCALL_NUM) = __NR_##name;	      \
-  register unsigned long __ret __asm__ (SYSCALL_RET);			      \
-  __asm__ __volatile__ ("bralid r17, 0x8; nop;"			      \
-			: "=r" (__ret)					      \
-			: "r" (__syscall), "r" (__a), "r" (__b), "r" (__c)      \
-			: SYSCALL_CLOBBERS);				      \
-  __syscall_return (type, __ret);					      \
-}
-
-#define _syscall4(type, name, atype, a, btype, b, ctype, c, dtype, d)	      \
-type name (atype a, btype b, ctype c, dtype d)				      \
-{									      \
-  register atype __a __asm__ (SYSCALL_ARG0) = a;			      \
-  register btype __b __asm__ (SYSCALL_ARG1) = b;			      \
-  register ctype __c __asm__ (SYSCALL_ARG2) = c;			      \
-  register dtype __d __asm__ (SYSCALL_ARG3) = d;			      \
-  register unsigned long __syscall __asm__ (SYSCALL_NUM) = __NR_##name;	      \
-  register unsigned long __ret __asm__ (SYSCALL_RET);			      \
-  __asm__ __volatile__ ("bralid r17, 0x8; nop;"			      \
-			: "=r" (__ret)					      \
-			: "r" (__syscall),				      \
-			"r" (__a), "r" (__b), "r" (__c), "r" (__d)	      \
-			: SYSCALL_CLOBBERS);				      \
-  __syscall_return (type, __ret);					      \
-}
-
-#define _syscall5(type, name, atype, a, btype, b, ctype, c, dtype, d, etype,e)\
-type name (atype a, btype b, ctype c, dtype d, etype e)			      \
-{									      \
-  register atype __a __asm__ (SYSCALL_ARG0) = a;			      \
-  register btype __b __asm__ (SYSCALL_ARG1) = b;			      \
-  register ctype __c __asm__ (SYSCALL_ARG2) = c;			      \
-  register dtype __d __asm__ (SYSCALL_ARG3) = d;			      \
-  register etype __e __asm__ (SYSCALL_ARG4) = e;			      \
-  register unsigned long __syscall __asm__ (SYSCALL_NUM) = __NR_##name;	      \
-  register unsigned long __ret __asm__ (SYSCALL_RET);			      \
-  __asm__ __volatile__ ("bralid r17, 0x8; nop;"				      \
-			: "=r" (__ret)					      \
-			: "r" (__syscall),				      \
-			"r" (__a), "r" (__b), "r" (__c), "r" (__d), "r" (__e) \
-			: SYSCALL_CLOBBERS);				      \
-  __syscall_return (type, __ret);					      \
-}
-
-#define _syscall6(type, name, atype, a, btype, b, ctype, c, dtype, d, etype, e, ftype, f) \
-type name (atype a, btype b, ctype c, dtype d, etype e, ftype f)	      \
-{									      \
-  register atype __a __asm__ (SYSCALL_ARG0) = a;			      \
-  register btype __b __asm__ (SYSCALL_ARG1) = b;			      \
-  register ctype __c __asm__ (SYSCALL_ARG2) = c;			      \
-  register dtype __d __asm__ (SYSCALL_ARG3) = d;			      \
-  register etype __e __asm__ (SYSCALL_ARG4) = e;			      \
-  register etype __f __asm__ (SYSCALL_ARG5) = f;			      \
-  register unsigned long __syscall __asm__ (SYSCALL_NUM) = __NR_##name;	      \
-  register unsigned long __ret __asm__ (SYSCALL_RET);			      \
-  __asm__ __volatile__ ("bralid r17, 0x8; nop;"			      \
-			: "=r" (__ret)					      \
-			: "r" (__syscall),				      \
-			"r" (__a), "r" (__b), "r" (__c), "r" (__d),	      \
-			"r" (__e), "r" (__f)				      \
-			: SYSCALL_CLOBBERS);				      \
-  __syscall_return (type, __ret);					      \
+#define __syscall_return(type, res)			 		\
+do {									\
+	/* user-visible error numbers are in the range -1 - -124:	\
+	   see <asm-microblaze/errno.h> */				\
+	if ((unsigned long)(res) >= (unsigned long)(-125)) {		\
+		errno = -(res);						\
+		res = -1;						\
+	}								\
+	return (type) (res);						\
+} while (0)
+
+#define _syscall0(type, name)						\
+type name (void)							\
+{									\
+	long __ret;							\
+	__asm__ __volatile__ ("bralid	r17, 0x8	\n\t"		\
+			      "addik	r12, r0, %1	\n\t"		\
+			      "addk	%0, r3, r0	\n\t"		\
+			      : "=r" (__ret)				\
+			      : "i" (__NR_##name)			\
+			      : SYSCALL_CLOBBERS);			\
+	__syscall_return (type, __ret);					\
+}
+
+#define _syscall1(type, name, type1, arg1)				\
+type name (type1 arg1)							\
+{									\
+	long __ret;							\
+	__asm__ __volatile__ ("addk	r5, r0, %2	\n\t"		\
+			      "bralid	r17, 0x8	\n\t"		\
+			      "addik	r12, r0, %1	\n\t"		\
+			      "addk	%0, r3, r0	\n\t"		\
+			      : "=r" (__ret)				\
+			      : "i" (__NR_##name),			\
+				"r" ((long)arg1)			\
+			      : "r5", SYSCALL_CLOBBERS);		\
+	__syscall_return (type, __ret);					\
+}
+
+#define _syscall2(type, name, type1, arg1, type2, arg2)			\
+type name (type1 arg1, type2 arg2)					\
+{									\
+	long __ret;							\
+	__asm__ __volatile__ ("addk	r5, r0, %2	\n\t"		\
+			      "addk	r6, r0, %3	\n\t"	   	\
+			      "bralid	r17, 0x8	\n\t"	   	\
+			      "addik	r12, r0, %1	\n\t"	   	\
+			      "addk	%0, r3, r0	\n\t"	   	\
+			      : "=r" (__ret)			    	\
+			      : "i" (__NR_##name),		      	\
+				"r" ((long)arg1),		       	\
+				"r" ((long)arg2)			\
+			      : "r5", "r6", SYSCALL_CLOBBERS);		\
+	__syscall_return (type, __ret);				 	\
+}
+
+#define _syscall3(type, name, type1, arg1, type2, arg2, type3, arg3)    \
+type name (type1 arg1, type2 arg2, type3 arg3)			  	\
+{								       	\
+	long __ret;						     	\
+	__asm__ __volatile__ ("addk	r5, r0, %2	\n\t"	   	\
+			      "addk	r6, r0, %3	\n\t"	   	\
+			      "addk	r7, r0, %4	\n\t"	   	\
+			      "bralid	r17, 0x8	\n\t"	   	\
+			      "addik	r12, r0, %1	\n\t"	   	\
+			      "addk	%0, r3, r0	\n\t"	   	\
+			      : "=r" (__ret)			    	\
+			      : "i" (__NR_##name),		      	\
+				"r" ((long)arg1),		       	\
+				"r" ((long)arg2),		       	\
+				"r" ((long)arg3)			\
+			      : "r5", "r6", "r7", SYSCALL_CLOBBERS);	\
+	__syscall_return (type, __ret);				 \
+}
+
+#define _syscall4(type, name, type1, arg1, type2, arg2, type3, arg3, type4, arg4) \
+type name (type1 arg1, type2 arg2, type3 arg3, type4 arg4)	      	\
+{								       	\
+	long __ret;						     	\
+	__asm__ __volatile__ ("addk	r5, r0, %2	\n\t"	   	\
+			      "addk	r6, r0, %3	\n\t"	   	\
+			      "addk	r7, r0, %4	\n\t"	   	\
+			      "addk	r8, r0, %5	\n\t"	   	\
+			      "bralid	r17, 0x8	\n\t"	   	\
+			      "addik	r12, r0, %1	\n\t"	   	\
+			      "addk	%0, r3, r0	\n\t"	   	\
+			      : "=r" (__ret)			    	\
+			      : "i" (__NR_##name),		      	\
+				"r" ((long)arg1),		       	\
+				"r" ((long)arg2),		       	\
+				"r" ((long)arg3),		       	\
+				"r" ((long)arg4)			\
+			      : "r5", "r6", "r6", "r8",SYSCALL_CLOBBERS);    \
+	__syscall_return (type, __ret);				 	\
+}
+
+#define _syscall5(type, name, type1, arg1, type2, arg2, type3, arg3, type4, arg4, type5, arg5) \
+type name (type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5)  \
+{								       	\
+	long __ret;						     	\
+	__asm__ __volatile__ ("addk	r5, r0, %2	\n\t"	   	\
+			      "addk	r6, r0, %3	\n\t"	   	\
+			      "addk	r7, r0, %4	\n\t"	   	\
+			      "addk	r8, r0, %5	\n\t"	   	\
+			      "addk	r9, r0, %6	\n\t"	   	\
+			      "bralid	r17, 0x8	\n\t"	   	\
+			      "addik	r12, r0, %1	\n\t"	   	\
+			      "addk	%0, r3, r0	\n\t"	   	\
+			      : "=r" (__ret)			    	\
+			      : "i" (__NR_##name),		      	\
+				"r" ((long)arg1),		       	\
+				"r" ((long)arg2),		       	\
+				"r" ((long)arg3),		       	\
+				"r" ((long)arg4),		       	\
+				"r" ((long)arg5)			\
+			      : "r5", "r6", "r7", "r8", "r9", SYSCALL_CLOBBERS);\
+	__syscall_return (type, __ret);				 	\
+}
+
+#define _syscall6(type, name, type1, arg1, type2, arg2, type3, arg3, type4, arg4, type5, arg5, type6, arg6) \
+type name (type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5, type6 arg6) \
+{									\
+	long __ret;							\
+	__asm__ __volatile__ ("addk	r5, r0, %2	\n\t"	   	\
+			      "addk	r6, r0, %3	\n\t"	   	\
+			      "addk	r7, r0, %4	\n\t"	   	\
+			      "addk	r8, r0, %5	\n\t"	   	\
+			      "addk	r9, r0, %6	\n\t"	   	\
+			      "addk	r10, r0, %7	\n\t"	   	\
+			      "bralid	r17, 0x8	\n\t"	   	\
+			      "addik	r12, r0, %1	\n\t"	   	\
+			      "addk	%0, r3, r0	\n\t"	   	\
+			      : "=r" (__ret)			    	\
+			      : "i" (__NR_##name),		      	\
+				"r" ((long)arg1),		       	\
+				"r" ((long)arg2),		       	\
+				"r" ((long)arg3),		       	\
+				"r" ((long)arg4),		       	\
+				"r" ((long)arg5),		       	\
+				"r" ((long)arg6)			\
+			      : "r5", "r6", "r7", "r8", "r9", "r10", SYSCALL_CLOBBERS);		      	\
+	__syscall_return (type, __ret);				 	\
 }
-		
 
 #ifdef __KERNEL_SYSCALLS__