summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdhemerval Zanella <adhemerval.zanella@linaro.org>2020-02-10 10:32:14 -0300
committerAndreas K. Huettel <dilfridge@gentoo.org>2020-03-09 11:49:41 +0100
commit49c2bdd46bb52ed367cc8754981f8e19bcf09a19 (patch)
treeb34ac38ad1f3dbeefe0cc320a80d49cc7d92f5e6
parentmicroblaze: Avoid clobbering register parameters in syscall (diff)
downloadglibc-49c2bdd46bb52ed367cc8754981f8e19bcf09a19.tar.gz
glibc-49c2bdd46bb52ed367cc8754981f8e19bcf09a19.tar.bz2
glibc-49c2bdd46bb52ed367cc8754981f8e19bcf09a19.zip
riscv: Avoid clobbering register parameters in syscall
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) (cherry picked from commit 74d9b0811eb4176ba314436a56f6f5fea96ba910)
-rw-r--r--sysdeps/unix/sysv/linux/riscv/sysdep.h84
1 files changed, 56 insertions, 28 deletions
diff --git a/sysdeps/unix/sysv/linux/riscv/sysdep.h b/sysdeps/unix/sysv/linux/riscv/sysdep.h
index 5470ea3d2a..6fc63852cf 100644
--- a/sysdeps/unix/sysv/linux/riscv/sysdep.h
+++ b/sysdeps/unix/sysv/linux/riscv/sysdep.h
@@ -173,10 +173,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) \
@@ -190,11 +191,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) \
@@ -208,12 +211,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) \
@@ -227,13 +233,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) \
@@ -247,14 +257,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) \
@@ -268,15 +283,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) \
@@ -291,16 +312,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) \