[PATCH v2 08/23] linux: Use generic __syscall_error for powerpc

Adhemerval Zanella adhemerval.zanella@linaro.org
Fri Nov 13 16:58:22 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 -
 .../powerpc/{sysdep.c => syscall_error.h}     | 18 ++++++------
 sysdeps/unix/sysv/linux/sparc/sysdep.c        | 28 ++++++++++++++++++-
 15 files changed, 54 insertions(+), 28 deletions(-)
 delete mode 100644 sysdeps/unix/sysv/linux/powerpc/rt-sysdep.c
 rename sysdeps/unix/sysv/linux/powerpc/{sysdep.c => syscall_error.h} (74%)

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/syscall_error.h
similarity index 74%
rename from sysdeps/unix/sysv/linux/powerpc/sysdep.c
rename to sysdeps/unix/sysv/linux/powerpc/syscall_error.h
index 1bf5ea6f62..924f12435d 100644
--- a/sysdeps/unix/sysv/linux/powerpc/sysdep.c
+++ b/sysdeps/unix/sysv/linux/powerpc/syscall_error.h
@@ -1,4 +1,5 @@
-/* Copyright (C) 1997-2020 Free Software Foundation, Inc.
+/* Linux wrappers for setting errno.  PowerPC version.
+   Copyright (C) 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
@@ -15,13 +16,10 @@
    License along with the GNU C Library; if not, see
    <https://www.gnu.org/licenses/>.  */
 
-#include <errno.h>
+#ifndef _SYSCALL_ERROR_H
+#define _SYSCALL_ERROR_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;
-}
+#define SYSCALL_ERROR_FUNC        1
+#define SYSCALL_ERROR_FUNC_ATTR
+
+#endif
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