This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
[PATCH 12/15] sparc: Avoid clobbering register parameters in syscall
- From: Adhemerval Zanella <adhemerval dot zanella at linaro dot org>
- To: libc-alpha at sourceware dot org
- Date: Mon, 10 Feb 2020 16:20:35 -0300
- Subject: [PATCH 12/15] sparc: Avoid clobbering register parameters in syscall
- References: <20200210192038.23588-1-adhemerval.zanella@linaro.org>
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(-)
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) : \
--
2.17.1