[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[patches] Fix ARM syscall argument loading
- To: patches@xxxxxxxxxx
- Subject: [patches] Fix ARM syscall argument loading
- From: "Joseph S. Myers" <joseph@xxxxxxxxxxxxxxxx>
- Date: Tue, 25 Nov 2008 16:31:48 +0000 (UTC)
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