public inbox for libc-stable@sourceware.org
 help / color / mirror / Atom feed
* [2.31 COMMITTED] riscv: Avoid clobbering register parameters in syscall
@ 2020-01-01  0:00 Aurelien Jarno
  0 siblings, 0 replies; only message in thread
From: Aurelien Jarno @ 2020-01-01  0:00 UTC (permalink / raw)
  To: libc-stable; +Cc: Adhemerval Zanella

From: Adhemerval Zanella <adhemerval.zanella@linaro.org>

The riscv 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 (bug 25523).

Checked with riscv64-linux-gnu-rv64imafdc-lp64d build.

(cherry picked from commit be74b42ee2a97009a6cd4fc90126add4a41c583b)
---
 sysdeps/unix/sysv/linux/riscv/sysdep.h | 84 +++++++++++++++++---------
 1 file changed, 56 insertions(+), 28 deletions(-)

diff --git a/sysdeps/unix/sysv/linux/riscv/sysdep.h b/sysdeps/unix/sysv/linux/riscv/sysdep.h
index 201bf9a91b9..2bd9b16f321 100644
--- a/sysdeps/unix/sysv/linux/riscv/sysdep.h
+++ b/sysdeps/unix/sysv/linux/riscv/sysdep.h
@@ -176,10 +176,11 @@
 # define internal_syscall1(number, err, arg0)				\
 ({ 									\
 	long int _sys_result;						\
+	long int _arg0 = (long int) (arg0);				\
 									\
 	{								\
 	register long int __a7 asm ("a7") = number;			\
-	register long int __a0 asm ("a0") = (long int) (arg0);		\
+	register long int __a0 asm ("a0") = _arg0;			\
 	__asm__ volatile ( 						\
 	"scall\n\t" 							\
 	: "+r" (__a0)							\
@@ -193,11 +194,13 @@
 # define internal_syscall2(number, err, arg0, arg1)	    		\
 ({ 									\
 	long int _sys_result;						\
+	long int _arg0 = (long int) (arg0);				\
+	long int _arg1 = (long int) (arg1);				\
 									\
 	{								\
 	register long int __a7 asm ("a7") = number;			\
-	register long int __a0 asm ("a0") = (long int) (arg0);		\
-	register long int __a1 asm ("a1") = (long int) (arg1);		\
+	register long int __a0 asm ("a0") = _arg0;			\
+	register long int __a1 asm ("a1") = _arg1;			\
 	__asm__ volatile ( 						\
 	"scall\n\t" 							\
 	: "+r" (__a0)							\
@@ -211,12 +214,15 @@
 # define internal_syscall3(number, err, arg0, arg1, arg2)      		\
 ({ 									\
 	long int _sys_result;						\
+	long int _arg0 = (long int) (arg0);				\
+	long int _arg1 = (long int) (arg1);				\
+	long int _arg2 = (long int) (arg2);				\
 									\
 	{								\
 	register long int __a7 asm ("a7") = number;			\
-	register long int __a0 asm ("a0") = (long int) (arg0);		\
-	register long int __a1 asm ("a1") = (long int) (arg1);		\
-	register long int __a2 asm ("a2") = (long int) (arg2);		\
+	register long int __a0 asm ("a0") = _arg0;			\
+	register long int __a1 asm ("a1") = _arg1;			\
+	register long int __a2 asm ("a2") = _arg2;			\
 	__asm__ volatile ( 						\
 	"scall\n\t" 							\
 	: "+r" (__a0)							\
@@ -230,13 +236,17 @@
 # define internal_syscall4(number, err, arg0, arg1, arg2, arg3)	  \
 ({ 									\
 	long int _sys_result;						\
+	long int _arg0 = (long int) (arg0);				\
+	long int _arg1 = (long int) (arg1);				\
+	long int _arg2 = (long int) (arg2);				\
+	long int _arg3 = (long int) (arg3);				\
 									\
 	{								\
 	register long int __a7 asm ("a7") = number;			\
-	register long int __a0 asm ("a0") = (long int) (arg0);		\
-	register long int __a1 asm ("a1") = (long int) (arg1);		\
-	register long int __a2 asm ("a2") = (long int) (arg2);		\
-	register long int __a3 asm ("a3") = (long int) (arg3);		\
+	register long int __a0 asm ("a0") = _arg0;			\
+	register long int __a1 asm ("a1") = _arg1;			\
+	register long int __a2 asm ("a2") = _arg2;			\
+	register long int __a3 asm ("a3") = _arg3;			\
 	__asm__ volatile ( 						\
 	"scall\n\t" 							\
 	: "+r" (__a0)							\
@@ -250,14 +260,19 @@
 # define internal_syscall5(number, err, arg0, arg1, arg2, arg3, arg4)   \
 ({ 									\
 	long int _sys_result;						\
+	long int _arg0 = (long int) (arg0);				\
+	long int _arg1 = (long int) (arg1);				\
+	long int _arg2 = (long int) (arg2);				\
+	long int _arg3 = (long int) (arg3);				\
+	long int _arg4 = (long int) (arg4);				\
 									\
 	{								\
 	register long int __a7 asm ("a7") = number;			\
-	register long int __a0 asm ("a0") = (long int) (arg0);		\
-	register long int __a1 asm ("a1") = (long int) (arg1);		\
-	register long int __a2 asm ("a2") = (long int) (arg2);		\
-	register long int __a3 asm ("a3") = (long int) (arg3);		\
-	register long int __a4 asm ("a4") = (long int) (arg4);		\
+	register long int __a0 asm ("a0") = _arg0;			\
+	register long int __a1 asm ("a1") = _arg1;			\
+	register long int __a2 asm ("a2") = _arg2;			\
+	register long int __a3 asm ("a3") = _arg3;			\
+	register long int __a4 asm ("a4") = _arg4;			\
 	__asm__ volatile ( 						\
 	"scall\n\t" 							\
 	: "+r" (__a0)							\
@@ -271,15 +286,21 @@
 # define internal_syscall6(number, err, arg0, arg1, arg2, arg3, arg4, arg5) \
 ({ 									\
 	long int _sys_result;						\
+	long int _arg0 = (long int) (arg0);				\
+	long int _arg1 = (long int) (arg1);				\
+	long int _arg2 = (long int) (arg2);				\
+	long int _arg3 = (long int) (arg3);				\
+	long int _arg4 = (long int) (arg4);				\
+	long int _arg5 = (long int) (arg5);				\
 									\
 	{								\
 	register long int __a7 asm ("a7") = number;			\
-	register long int __a0 asm ("a0") = (long int) (arg0);		\
-	register long int __a1 asm ("a1") = (long int) (arg1);		\
-	register long int __a2 asm ("a2") = (long int) (arg2);		\
-	register long int __a3 asm ("a3") = (long int) (arg3);		\
-	register long int __a4 asm ("a4") = (long int) (arg4);		\
-	register long int __a5 asm ("a5") = (long int) (arg5);		\
+	register long int __a0 asm ("a0") = _arg0;			\
+	register long int __a1 asm ("a1") = _arg1;			\
+	register long int __a2 asm ("a2") = _arg2;			\
+	register long int __a3 asm ("a3") = _arg3;			\
+	register long int __a4 asm ("a4") = _arg4;			\
+	register long int __a5 asm ("a5") = _arg5;			\
 	__asm__ volatile ( 						\
 	"scall\n\t" 							\
 	: "+r" (__a0)							\
@@ -294,16 +315,23 @@
 # define internal_syscall7(number, err, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \
 ({ 									\
 	long int _sys_result;						\
+	long int _arg0 = (long int) (arg0);				\
+	long int _arg1 = (long int) (arg1);				\
+	long int _arg2 = (long int) (arg2);				\
+	long int _arg3 = (long int) (arg3);				\
+	long int _arg4 = (long int) (arg4);				\
+	long int _arg5 = (long int) (arg5);				\
+	long int _arg6 = (long int) (arg6);				\
 									\
 	{								\
 	register long int __a7 asm ("a7") = number;			\
-	register long int __a0 asm ("a0") = (long int) (arg0);		\
-	register long int __a1 asm ("a1") = (long int) (arg1);		\
-	register long int __a2 asm ("a2") = (long int) (arg2);		\
-	register long int __a3 asm ("a3") = (long int) (arg3);		\
-	register long int __a4 asm ("a4") = (long int) (arg4);		\
-	register long int __a5 asm ("a5") = (long int) (arg5);		\
-	register long int __a6 asm ("a6") = (long int) (arg6);		\
+	register long int __a0 asm ("a0") = _arg0;			\
+	register long int __a1 asm ("a1") = _arg1;			\
+	register long int __a2 asm ("a2") = _arg2;			\
+	register long int __a3 asm ("a3") = _arg3;			\
+	register long int __a4 asm ("a4") = _arg4;			\
+	register long int __a5 asm ("a5") = _arg5;			\
+	register long int __a6 asm ("a6") = _arg6;			\
 	__asm__ volatile ( 						\
 	"scall\n\t" 							\
 	: "+r" (__a0)							\
-- 
2.24.1

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2020-02-16 13:01 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-01-01  0:00 [2.31 COMMITTED] riscv: Avoid clobbering register parameters in syscall Aurelien Jarno

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).