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

[patches] Fix ARM syscall argument loading



This patch fixes a problem observed with ARM syscall argument loading for 
Thumb-2, where a call to sched_getaffinity in 
sysdeps/unix/sysv/linux/sched_setaffinity.c has getpid () as one of the 
arguments, and calling getpid () clobbers registers into which some of the 
arguments have been loaded.  The GCC manual has warnings about using 
register variables for call clobbered registers as asm arguments with such 
initializers, and this patch implements the recommended fix of computing 
all the arguments before loading them in the registers.  The structure of 
the macros used to do this is similar to that in 
sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep.h.  Applied to trunk, 2.9 
and 2.8 branches.

(I only observed the problem for Thumb-2, but it seems potentially equally 
relevant to ARM mode.)

Index: sysdeps/unix/sysv/linux/arm/sysdep.h
===================================================================
--- sysdeps/unix/sysv/linux/arm/sysdep.h	(revision 7381)
+++ sysdeps/unix/sysv/linux/arm/sysdep.h	(working copy)
@@ -238,32 +238,39 @@
 #define LOAD_ARGS_0()
 #define ASM_ARGS_0
 #define LOAD_ARGS_1(a1)				\
-  _a1 = (int) (a1);				\
-  LOAD_ARGS_0 ()
+  int _a1tmp = (int) (a1);			\
+  LOAD_ARGS_0 ()				\
+  _a1 = _a1tmp;
 #define ASM_ARGS_1	ASM_ARGS_0, "r" (_a1)
 #define LOAD_ARGS_2(a1, a2)			\
-  register int _a2 asm ("a2") = (int) (a2);	\
-  LOAD_ARGS_1 (a1)
+  int _a2tmp = (int) (a2);			\
+  LOAD_ARGS_1 (a1)				\
+  register int _a2 asm ("a2") = _a2tmp;
 #define ASM_ARGS_2	ASM_ARGS_1, "r" (_a2)
 #define LOAD_ARGS_3(a1, a2, a3)			\
-  register int _a3 asm ("a3") = (int) (a3);	\
-  LOAD_ARGS_2 (a1, a2)
+  int _a3tmp = (int) (a3);			\
+  LOAD_ARGS_2 (a1, a2)				\
+  register int _a3 asm ("a3") = _a3tmp;
 #define ASM_ARGS_3	ASM_ARGS_2, "r" (_a3)
 #define LOAD_ARGS_4(a1, a2, a3, a4)		\
-  register int _a4 asm ("a4") = (int) (a4);	\
-  LOAD_ARGS_3 (a1, a2, a3)
+  int _a4tmp = (int) (a4);			\
+  LOAD_ARGS_3 (a1, a2, a3)			\
+  register int _a4 asm ("a4") = _a4tmp;
 #define ASM_ARGS_4	ASM_ARGS_3, "r" (_a4)
 #define LOAD_ARGS_5(a1, a2, a3, a4, a5)		\
-  register int _v1 asm ("v1") = (int) (a5);	\
-  LOAD_ARGS_4 (a1, a2, a3, a4)
+  int _v1tmp = (int) (a5);			\
+  LOAD_ARGS_4 (a1, a2, a3, a4)			\
+  register int _v1 asm ("v1") = _v1tmp;
 #define ASM_ARGS_5	ASM_ARGS_4, "r" (_v1)
 #define LOAD_ARGS_6(a1, a2, a3, a4, a5, a6)	\
-  register int _v2 asm ("v2") = (int) (a6);	\
-  LOAD_ARGS_5 (a1, a2, a3, a4, a5)
+  int _v2tmp = (int) (a6);			\
+  LOAD_ARGS_5 (a1, a2, a3, a4, a5)		\
+  register int _v2 asm ("v2") = _v2tmp;
 #define ASM_ARGS_6	ASM_ARGS_5, "r" (_v2)
 #define LOAD_ARGS_7(a1, a2, a3, a4, a5, a6, a7)	\
-  register int _v3 asm ("v3") = (int) (a7);	\
-  LOAD_ARGS_6 (a1, a2, a3, a4, a5, a6)
+  int _v3tmp = (int) (a7);			\
+  LOAD_ARGS_6 (a1, a2, a3, a4, a5, a6)		\
+  register int _v3 asm ("v3") = _v3tmp;
 #define ASM_ARGS_7	ASM_ARGS_6, "r" (_v3)
 
 /* We can't implement non-constant syscalls directly since the syscall
Index: ChangeLog.eglibc
===================================================================
--- ChangeLog.eglibc	(revision 7381)
+++ ChangeLog.eglibc	(working copy)
@@ -1,3 +1,10 @@
+2008-11-25  Joseph Myers  <joseph@xxxxxxxxxxxxxxxx>
+
+	* sysdeps/unix/sysv/linux/arm/sysdep.h (LOAD_ARGS_1, LOAD_ARGS_2,
+	LOAD_ARGS_3, LOAD_ARGS_4, LOAD_ARGS_5, LOAD_ARGS_6, LOAD_ARGS_7):
+	Load all arguments into temporary variables before loading into
+	registers.
+
 2008-11-20  Joseph Myers  <joseph@xxxxxxxxxxxxxxxx>
 
 	* sysdeps/arm/tls-macros.h (ARM_PC_OFFSET): Define.

-- 
Joseph S. Myers
joseph@xxxxxxxxxxxxxxxx