diff mbox

[12/15] sparc: Avoid clobbering register parameters in syscall

Message ID 20200210192038.23588-12-adhemerval.zanella@linaro.org
State New
Headers show

Commit Message

Adhemerval Zanella Feb. 10, 2020, 7:20 p.m. UTC
The sparc INTERNAL_SYSCALL macro might clobber the register
parameter if the argument itself might clobber any register (a function
call for instance).

This patch fixes it by using temporary variables for the expressions
between the register assignments (as indicated by GCC documentation,
6.47.5.2 Specifying Registers for Local Variables).

It is similar to the fix done for MIPS (BZ#25523).

Checked on sparc64-linux-gnu and sparcv9-linux-gnu.
---
 sysdeps/unix/sysv/linux/sparc/sysdep.h | 78 +++++++++++++++++---------
 1 file changed, 52 insertions(+), 26 deletions(-)

Comments

Florian Weimer Feb. 11, 2020, 11:22 a.m. UTC | #1
* Adhemerval Zanella:

> The sparc INTERNAL_SYSCALL macro might clobber the register
> parameter if the argument itself might clobber any register (a function
> call for instance).
>
> This patch fixes it by using temporary variables for the expressions
> between the register assignments (as indicated by GCC documentation,
> 6.47.5.2 Specifying Registers for Local Variables).
>
> It is similar to the fix done for MIPS (BZ#25523).

(bug 25523) for the bug reference.  You may also consider switching to
long int instead of long, given that you change most of the code anyway.
Otherwise looks good.

Thanks,
Florian
Adhemerval Zanella Feb. 11, 2020, 7:17 p.m. UTC | #2
On 11/02/2020 08:22, Florian Weimer wrote:
> * Adhemerval Zanella:
> 
>> The sparc INTERNAL_SYSCALL macro might clobber the register
>> parameter if the argument itself might clobber any register (a function
>> call for instance).
>>
>> This patch fixes it by using temporary variables for the expressions
>> between the register assignments (as indicated by GCC documentation,
>> 6.47.5.2 Specifying Registers for Local Variables).
>>
>> It is similar to the fix done for MIPS (BZ#25523).
> 
> (bug 25523) for the bug reference.  You may also consider switching to
> long int instead of long, given that you change most of the code anyway.
> Otherwise looks good.

Ack I have changed to long int on my local branch.
diff mbox

Patch

diff --git a/sysdeps/unix/sysv/linux/sparc/sysdep.h b/sysdeps/unix/sysv/linux/sparc/sysdep.h
index 67efa6f029..e2a12349a1 100644
--- a/sysdeps/unix/sysv/linux/sparc/sysdep.h
+++ b/sysdeps/unix/sysv/linux/sparc/sysdep.h
@@ -87,8 +87,9 @@ 
 
 #define internal_syscall1(string,err,name,arg1)				\
 ({									\
+	long _arg1 = (long) (arg1);					\
 	register long __err __asm__("g1") = (name);			\
-	register long __o0 __asm__ ("o0") = (long)(arg1);		\
+	register long __o0 __asm__ ("o0") = _arg1;			\
 	__asm __volatile (string : "=r" (__err), "=r" (__o0) :		\
 			  "0" (__err), "1" (__o0) :			\
 			  __SYSCALL_CLOBBERS);				\
@@ -97,9 +98,11 @@ 
 
 #define internal_syscall2(string,err,name,arg1,arg2)			\
 ({									\
+	long _arg1 = (long) (arg1);					\
+	long _arg2 = (long) (arg2);					\
 	register long __err __asm__("g1") = (name);			\
-	register long __o0 __asm__ ("o0") = (long)(arg1);		\
-	register long __o1 __asm__ ("o1") = (long)(arg2);		\
+	register long __o0 __asm__ ("o0") = _arg1;			\
+	register long __o1 __asm__ ("o1") = _arg2;			\
 	__asm __volatile (string : "=r" (__err), "=r" (__o0) :		\
 			  "0" (__err), "1" (__o0), "r" (__o1) :		\
 			  __SYSCALL_CLOBBERS);				\
@@ -108,10 +111,13 @@ 
 
 #define internal_syscall3(string,err,name,arg1,arg2,arg3)		\
 ({									\
+	long _arg1 = (long) (arg1);					\
+	long _arg2 = (long) (arg2);					\
+	long _arg3 = (long) (arg3);					\
 	register long __err __asm__("g1") = (name);			\
-	register long __o0 __asm__ ("o0") = (long)(arg1);		\
-	register long __o1 __asm__ ("o1") = (long)(arg2);		\
-	register long __o2 __asm__ ("o2") = (long)(arg3);		\
+	register long __o0 __asm__ ("o0") = _arg1;			\
+	register long __o1 __asm__ ("o1") = _arg2;			\
+	register long __o2 __asm__ ("o2") = _arg3;			\
 	__asm __volatile (string : "=r" (__err), "=r" (__o0) :		\
 			  "0" (__err), "1" (__o0), "r" (__o1),		\
 			  "r" (__o2) :					\
@@ -121,11 +127,15 @@ 
 
 #define internal_syscall4(string,err,name,arg1,arg2,arg3,arg4)		\
 ({									\
+	long _arg1 = (long) (arg1);					\
+	long _arg2 = (long) (arg2);					\
+	long _arg3 = (long) (arg3);					\
+	long _arg4 = (long) (arg4);					\
 	register long __err __asm__("g1") = (name);			\
-	register long __o0 __asm__ ("o0") = (long)(arg1);		\
-	register long __o1 __asm__ ("o1") = (long)(arg2);		\
-	register long __o2 __asm__ ("o2") = (long)(arg3);		\
-	register long __o3 __asm__ ("o3") = (long)(arg4);		\
+	register long __o0 __asm__ ("o0") = _arg1;			\
+	register long __o1 __asm__ ("o1") = _arg2;			\
+	register long __o2 __asm__ ("o2") = _arg3;			\
+	register long __o3 __asm__ ("o3") = _arg4;			\
 	__asm __volatile (string : "=r" (__err), "=r" (__o0) :		\
 			  "0" (__err), "1" (__o0), "r" (__o1),		\
 			  "r" (__o2), "r" (__o3) :			\
@@ -135,12 +145,17 @@ 
 
 #define internal_syscall5(string,err,name,arg1,arg2,arg3,arg4,arg5)	\
 ({									\
+	long _arg1 = (long) (arg1);					\
+	long _arg2 = (long) (arg2);					\
+	long _arg3 = (long) (arg3);					\
+	long _arg4 = (long) (arg4);					\
+	long _arg5 = (long) (arg5);					\
 	register long __err __asm__("g1") = (name);			\
-	register long __o0 __asm__ ("o0") = (long)(arg1);		\
-	register long __o1 __asm__ ("o1") = (long)(arg2);		\
-	register long __o2 __asm__ ("o2") = (long)(arg3);		\
-	register long __o3 __asm__ ("o3") = (long)(arg4);		\
-	register long __o4 __asm__ ("o4") = (long)(arg5);		\
+	register long __o0 __asm__ ("o0") = _arg1;			\
+	register long __o1 __asm__ ("o1") = _arg2;			\
+	register long __o2 __asm__ ("o2") = _arg3;			\
+	register long __o3 __asm__ ("o3") = _arg4;			\
+	register long __o4 __asm__ ("o4") = _arg5;			\
 	__asm __volatile (string : "=r" (__err), "=r" (__o0) :		\
 			  "0" (__err), "1" (__o0), "r" (__o1),		\
 			  "r" (__o2), "r" (__o3), "r" (__o4) :		\
@@ -150,13 +165,19 @@ 
 
 #define internal_syscall6(string,err,name,arg1,arg2,arg3,arg4,arg5,arg6)\
 ({									\
+	long _arg1 = (long) (arg1);					\
+	long _arg2 = (long) (arg2);					\
+	long _arg3 = (long) (arg3);					\
+	long _arg4 = (long) (arg4);					\
+	long _arg5 = (long) (arg5);					\
+	long _arg6 = (long) (arg6);					\
 	register long __err __asm__("g1") = (name);			\
-	register long __o0 __asm__ ("o0") = (long)(arg1);		\
-	register long __o1 __asm__ ("o1") = (long)(arg2);		\
-	register long __o2 __asm__ ("o2") = (long)(arg3);		\
-	register long __o3 __asm__ ("o3") = (long)(arg4);		\
-	register long __o4 __asm__ ("o4") = (long)(arg5);		\
-	register long __o5 __asm__ ("o5") = (long)(arg6);		\
+	register long __o0 __asm__ ("o0") = _arg1;			\
+	register long __o1 __asm__ ("o1") = _arg2;			\
+	register long __o2 __asm__ ("o2") = _arg3;			\
+	register long __o3 __asm__ ("o3") = _arg4;			\
+	register long __o4 __asm__ ("o4") = _arg5;			\
+	register long __o5 __asm__ ("o5") = _arg6;			\
 	__asm __volatile (string : "=r" (__err), "=r" (__o0) :		\
 			  "0" (__err), "1" (__o0), "r" (__o1),		\
 			  "r" (__o2), "r" (__o3), "r" (__o4),		\
@@ -167,11 +188,16 @@ 
 
 #define INLINE_CLONE_SYSCALL(arg1,arg2,arg3,arg4,arg5)			\
 ({									\
-	register long __o0 __asm__ ("o0") = (long)(arg1);		\
-	register long __o1 __asm__ ("o1") = (long)(arg2);		\
-	register long __o2 __asm__ ("o2") = (long)(arg3);		\
-	register long __o3 __asm__ ("o3") = (long)(arg4);		\
-	register long __o4 __asm__ ("o4") = (long)(arg5);		\
+	long _arg1 = (long) (arg1);					\
+	long _arg2 = (long) (arg2);					\
+	long _arg3 = (long) (arg3);					\
+	long _arg4 = (long) (arg4);					\
+	long _arg5 = (long) (arg5);					\
+	register long __o0 __asm__ ("o0") = _arg1;			\
+	register long __o1 __asm__ ("o1") = _arg2;			\
+	register long __o2 __asm__ ("o2") = _arg3;			\
+	register long __o3 __asm__ ("o3") = _arg4;			\
+	register long __o4 __asm__ ("o4") = _arg5;			\
 	register long __g1 __asm__ ("g1") = __NR_clone;			\
 	__asm __volatile (__SYSCALL_STRING :				\
 			  "=r" (__g1), "=r" (__o0), "=r" (__o1)	:	\