[PATCH 09/23] linux: Use generic __syscall_error for powerpc
Adhemerval Zanella
adhemerval.zanella@linaro.org
Mon Nov 9 20:18:12 GMT 2020
The powerpc kABI returns a positive value on 'r3' register for failure
case (the syscall error is signaled on CR0), different than usual Linux
kABI with return a negative value in range of [-4096,0). The arch
specific__syscall_error thus has a different ABI than the generic one,
which requires fixing both the inline syscall wrappers and some assembly
implementation that calls __syscall_error directly.
Using an inline function for __syscall_error is slight better for
powerpc64{le} and only a small code increase on powerpc32:
--- sizes-powerpc-linux-gnu.outline
+++ sizes-powerpc-linux-gnu.inline
@@ -1,8 +1,8 @@
text data bss dec hex filename
-1759918 19900 9348 1789166 1b4cee libc.so
- 176605 7516 188 184309 2cff5 elf/ld.so
- 131959 1776 8352 142087 22b07 nptl/libpthread.so
- 32058 872 160 33090 8142 rt/librt.so
+1767602 19900 9348 1796850 1b6af2 libc.so
+ 177221 7516 188 184925 2d25d elf/ld.so
+ 132575 1776 8352 142703 22d6f nptl/libpthread.so
+ 32350 872 160 33382 8266 rt/librt.so
--- sizes-powerpc64-linux-gnu.outline
+++ sizes-powerpc64-linux-gnu.inline
@@ -1,8 +1,8 @@
text data bss dec hex filename
-2035762 95184 15048 2145994 20beca libc.so
- 258573 13104 504 272181 42735 elf/ld.so
- 154913 8240 18656 181809 2c631 nptl/libpthread.so
- 36875 2404 3704 42983 a7e7 rt/librt.so
+2031758 95184 15048 2141990 20af26 libc.so
+ 257881 13104 504 271489 42481 elf/ld.so
+ 154349 8240 18656 181245 2c3fd nptl/libpthread.so
+ 36511 2404 3704 42619 a67b rt/librt.so
--- sizes-powerpc64le-linux-gnu.outline
+++ sizes-powerpc64le-linux-gnu.inline
@@ -1,8 +1,8 @@
text data bss dec hex filename
-2031374 22464 14872 2068710 1f90e6 libc.so
- 208066 7832 416 216314 34cfa elf/ld.so
- 137717 1248 17328 156293 26285 nptl/libpthread.so
- 31918 716 728 33362 8252 rt/librt.so
+2027838 22464 14872 2065174 1f8316 libc.so
+ 207426 7832 416 215674 34a7a elf/ld.so
+ 137149 1248 17328 155725 2604d nptl/libpthread.so
+ 31490 716 728 32934 80a6 rt/librt.so
Checked on powerpc-linux-gnu, powerpc64-linux-gnu, and
powerpc64le-linux-gnu.
---
sysdeps/powerpc/powerpc32/sysdep.h | 1 +
sysdeps/powerpc/powerpc64/sysdep.h | 7 +++--
sysdeps/unix/sysv/linux/powerpc/Makefile | 7 -----
.../unix/sysv/linux/powerpc/powerpc32/brk.S | 1 +
.../unix/sysv/linux/powerpc/powerpc32/clone.S | 3 +-
.../sysv/linux/powerpc/powerpc32/getcontext.S | 2 ++
.../linux/powerpc/powerpc32/makecontext.S | 2 +-
.../powerpc/powerpc32/nofpu/getcontext.S | 2 +-
.../powerpc/powerpc32/nofpu/setcontext.S | 2 +-
.../powerpc/powerpc32/nofpu/swapcontext.S | 2 +-
.../sysv/linux/powerpc/powerpc32/setcontext.S | 3 +-
.../linux/powerpc/powerpc32/swapcontext.S | 3 +-
sysdeps/unix/sysv/linux/powerpc/rt-sysdep.c | 1 -
sysdeps/unix/sysv/linux/powerpc/sysdep.c | 27 ------------------
sysdeps/unix/sysv/linux/powerpc/sysdep.h | 2 ++
sysdeps/unix/sysv/linux/sparc/sysdep.c | 28 ++++++++++++++++++-
16 files changed, 48 insertions(+), 45 deletions(-)
delete mode 100644 sysdeps/unix/sysv/linux/powerpc/rt-sysdep.c
delete mode 100644 sysdeps/unix/sysv/linux/powerpc/sysdep.c
diff --git a/sysdeps/powerpc/powerpc32/sysdep.h b/sysdeps/powerpc/powerpc32/sysdep.h
index 829eec266a..47d3aa4339 100644
--- a/sysdeps/powerpc/powerpc32/sysdep.h
+++ b/sysdeps/powerpc/powerpc32/sysdep.h
@@ -113,6 +113,7 @@ GOT_LABEL: ; \
#define PSEUDO_RET \
bnslr+; \
+ neg 3,3; \
b __syscall_error@local
#define ret PSEUDO_RET
diff --git a/sysdeps/powerpc/powerpc64/sysdep.h b/sysdeps/powerpc/powerpc64/sysdep.h
index d557098898..e7496a979a 100644
--- a/sysdeps/powerpc/powerpc64/sysdep.h
+++ b/sysdeps/powerpc/powerpc64/sysdep.h
@@ -277,13 +277,13 @@ LT_LABELSUFFIX(name,_name_end): ; \
DO_CALL (SYS_ify (syscall_name))
#ifdef SHARED
-#define TAIL_CALL_SYSCALL_ERROR \
+#define _TAIL_CALL_SYSCALL_ERROR \
b JUMPTARGET (NOTOC (__syscall_error))
#else
/* Static version might be linked into a large app with a toc exceeding
64k. We can't put a toc adjusting stub on a plain branch, so can't
tail call __syscall_error. */
-#define TAIL_CALL_SYSCALL_ERROR \
+#define _TAIL_CALL_SYSCALL_ERROR \
.ifdef .Local_syscall_error; \
b .Local_syscall_error; \
.else; \
@@ -303,6 +303,9 @@ LT_LABELSUFFIX(name,_name_end): ; \
blr; \
.endif
#endif
+#define TAIL_CALL_SYSCALL_ERROR \
+ neg 3,3; \
+ _TAIL_CALL_SYSCALL_ERROR
#define PSEUDO_RET \
bnslr+; \
diff --git a/sysdeps/unix/sysv/linux/powerpc/Makefile b/sysdeps/unix/sysv/linux/powerpc/Makefile
index cc2f804d86..9610edd305 100644
--- a/sysdeps/unix/sysv/linux/powerpc/Makefile
+++ b/sysdeps/unix/sysv/linux/powerpc/Makefile
@@ -3,11 +3,6 @@ abi-32-condition := __WORDSIZE == 32
abi-64-v1-condition := __WORDSIZE == 64 && _CALL_ELF != 2
abi-64-v2-condition := __WORDSIZE == 64 && _CALL_ELF == 2
-ifeq ($(subdir),rt)
-librt-routines += rt-sysdep
-librt-shared-only-routines += rt-sysdep
-endif
-
ifeq ($(subdir),stdlib)
gen-as-const-headers += ucontext_i.sym
endif
@@ -31,8 +26,6 @@ tests += test-powerpc-linux-sysconf
endif
ifeq ($(subdir),nptl)
-libpthread-routines += sysdep
libpthread-sysdep_routines += elision-lock elision-unlock elision-timed \
elision-trylock
-libpthread-shared-only-routines += sysdep
endif
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/brk.S b/sysdeps/unix/sysv/linux/powerpc/powerpc32/brk.S
index f3b960795e..8cbe17ef1e 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/brk.S
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/brk.S
@@ -46,6 +46,7 @@ ENTRY (__brk)
li r3,0
blelr+
li r3,ENOMEM
+ neg r3,r3
b __syscall_error@local
END (__brk)
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/clone.S b/sysdeps/unix/sysv/linux/powerpc/powerpc32/clone.S
index ba0faaf69c..41e5e5fe2e 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/clone.S
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/clone.S
@@ -83,10 +83,11 @@ L(parent):
lmw r28,16(r1)
addi r1,r1,32
bnslr+
+ neg r3,r3
b __syscall_error@local
L(badargs):
- li r3,EINVAL
+ li r3,-EINVAL
b __syscall_error@local
cfi_startproc
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/getcontext.S b/sysdeps/unix/sysv/linux/powerpc/powerpc32/getcontext.S
index 9f65033b7e..c7c78d63c5 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/getcontext.S
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/getcontext.S
@@ -41,6 +41,7 @@ ENTRY (__getcontext)
li r3,0
blr
1:
+ neg r3,r3
b __syscall_error@local
END(__getcontext)
@@ -69,6 +70,7 @@ compat_symbol (libc, __novec_getcontext, getcontext, GLIBC_2_3_3)
compat_text_section
ENTRY (__getcontext_stub)
li r3,ENOSYS
+ neg r3,r3
b __syscall_error@local
END (__getcontext_stub)
.previous
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/makecontext.S b/sysdeps/unix/sysv/linux/powerpc/powerpc32/makecontext.S
index 873edf14a8..43cc88cb9f 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/makecontext.S
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/makecontext.S
@@ -216,7 +216,7 @@ compat_symbol (libc, __novec_makecontext, makecontext, GLIBC_2_3_3)
compat_text_section
ENTRY (__makecontext_stub)
- li r3,ENOSYS
+ li r3,-ENOSYS
b __syscall_error@local
END (__makecontext_stub)
.previous
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/getcontext.S b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/getcontext.S
index 3cbbd32c31..a2126f4627 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/getcontext.S
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/getcontext.S
@@ -48,7 +48,7 @@ compat_symbol (libc, __novec_getcontext, getcontext, GLIBC_2_3_3)
compat_text_section
ENTRY (__getcontext_stub)
- li r3,ENOSYS
+ li r3,-ENOSYS
b __syscall_error@local
END (__getcontext_stub)
.previous
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/setcontext.S b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/setcontext.S
index 5adf7fb5ba..b9f9c21b66 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/setcontext.S
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/setcontext.S
@@ -48,7 +48,7 @@ compat_symbol (libc, __novec_setcontext, setcontext, GLIBC_2_3_3)
compat_text_section
ENTRY (__setcontext_stub)
- li r3,ENOSYS
+ li r3,-ENOSYS
b __syscall_error@local
END (__setcontext_stub)
.previous
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/swapcontext.S b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/swapcontext.S
index e4aec0ff96..d7263e5fb8 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/swapcontext.S
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/swapcontext.S
@@ -48,7 +48,7 @@ compat_symbol (libc, __novec_swapcontext, swapcontext, GLIBC_2_3_3)
compat_text_section
ENTRY (__swapcontext_stub)
- li r3,ENOSYS
+ li r3,-ENOSYS
b __syscall_error@local
END (__swapcontext_stub)
.previous
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/setcontext.S b/sysdeps/unix/sysv/linux/powerpc/powerpc32/setcontext.S
index 7bcb2d990b..3cb5021917 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/setcontext.S
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/setcontext.S
@@ -42,6 +42,7 @@ ENTRY (__setcontext)
li r3,0
blr
1:
+ neg r3,r3
b __syscall_error@local
END(__setcontext)
@@ -70,7 +71,7 @@ compat_symbol (libc, __novec_setcontext, setcontext, GLIBC_2_3_3)
compat_text_section
ENTRY (__setcontext_stub)
- li r3,ENOSYS
+ li r3,-ENOSYS
b __syscall_error@local
END (__setcontext_stub)
.previous
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/swapcontext.S b/sysdeps/unix/sysv/linux/powerpc/powerpc32/swapcontext.S
index cd359d4a8a..53190028c5 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/swapcontext.S
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/swapcontext.S
@@ -40,6 +40,7 @@ ENTRY (__swapcontext)
li r3,0
blr
1:
+ neg r3,r3
b __syscall_error@local
END(__swapcontext)
@@ -68,7 +69,7 @@ compat_symbol (libc, __novec_swapcontext, swapcontext, GLIBC_2_3_3)
compat_text_section
ENTRY (__swapcontext_stub)
- li r3,ENOSYS
+ li r3,-ENOSYS
b __syscall_error@local
END (__swapcontext_stub)
.previous
diff --git a/sysdeps/unix/sysv/linux/powerpc/rt-sysdep.c b/sysdeps/unix/sysv/linux/powerpc/rt-sysdep.c
deleted file mode 100644
index 3ff55952e2..0000000000
--- a/sysdeps/unix/sysv/linux/powerpc/rt-sysdep.c
+++ /dev/null
@@ -1 +0,0 @@
-#include <sysdep.c>
diff --git a/sysdeps/unix/sysv/linux/powerpc/sysdep.c b/sysdeps/unix/sysv/linux/powerpc/sysdep.c
deleted file mode 100644
index 1bf5ea6f62..0000000000
--- a/sysdeps/unix/sysv/linux/powerpc/sysdep.c
+++ /dev/null
@@ -1,27 +0,0 @@
-/* Copyright (C) 1997-2020 Free Software Foundation, Inc.
- This file is part of the GNU C Library.
-
- The GNU C Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- The GNU C Library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with the GNU C Library; if not, see
- <https://www.gnu.org/licenses/>. */
-
-#include <errno.h>
-
-/* This routine is jumped to by all the syscall handlers, to stash
- an error number into errno. */
-int
-__syscall_error (int err_no)
-{
- __set_errno (err_no);
- return -1;
-}
diff --git a/sysdeps/unix/sysv/linux/powerpc/sysdep.h b/sysdeps/unix/sysv/linux/powerpc/sysdep.h
index b2bca598b9..31fa148ded 100644
--- a/sysdeps/unix/sysv/linux/powerpc/sysdep.h
+++ b/sysdeps/unix/sysv/linux/powerpc/sysdep.h
@@ -19,6 +19,8 @@
#ifndef _LINUX_POWERPC_SYSDEP_H
#define _LINUX_POWERPC_SYSDEP_H 1
+#define SYSCALL_ERROR_FUNC
+
#include <sysdeps/unix/sysv/linux/sysdep.h>
#include <sysdeps/unix/powerpc/sysdep.h>
#include <tls.h>
diff --git a/sysdeps/unix/sysv/linux/sparc/sysdep.c b/sysdeps/unix/sysv/linux/sparc/sysdep.c
index f86414570d..1bf5ea6f62 100644
--- a/sysdeps/unix/sysv/linux/sparc/sysdep.c
+++ b/sysdeps/unix/sysv/linux/sparc/sysdep.c
@@ -1 +1,27 @@
-#include <sysdeps/unix/sysv/linux/powerpc/sysdep.c>
+/* Copyright (C) 1997-2020 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+
+/* This routine is jumped to by all the syscall handlers, to stash
+ an error number into errno. */
+int
+__syscall_error (int err_no)
+{
+ __set_errno (err_no);
+ return -1;
+}
--
2.25.1
More information about the Libc-alpha
mailing list