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

login
register
mail settings
Submitter Adhemerval Zanella Netto
Date Feb. 10, 2020, 7:20 p.m.
Message ID <20200210192038.23588-12-adhemerval.zanella@linaro.org>
Download mbox | patch
Permalink /patch/37878/
State New
Headers show

Comments

Adhemerval Zanella Netto - Feb. 10, 2020, 7:20 p.m.
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(-)
Florian Weimer - Feb. 11, 2020, 11:22 a.m.
* 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 Netto - Feb. 11, 2020, 7:17 p.m.
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.

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)	:	\