[PATCH 23/23] linux: Use generic __syscall_error for mips

Adhemerval Zanella adhemerval.zanella@linaro.org
Mon Nov 9 20:18:26 GMT 2020


The mips kABI returns a positive value on 'v0 ($2)' register
for failure case, different than usual Linux kABI with return
a negative value in range of [-4096,0).  To adjust mips to use
the generic __syscall_error requires to change both the inline
syscall and some assembly implementation that call __syscall_error
directly.

Also, using an extern call to __syscall_error on mips results in
more code size:

--- sizes-mips64-linux-gnu.inline
+++ sizes-mips64-linux-gnu.outline
    text           data     bss     dec     hex filename
-1706692          39428   15584 1761704  1ae1a8 libc.so
- 164384           7904     396  172684   2a28c elf/ld.so
- 126357           1912   16720  144989   2365d nptl/libpthread.so
-  30260            988     272   31520    7b20 rt/librt.so
+1708116          39436   15584 1763136  1ae740 libc.so
+ 164592           7904     396  172892   2a35c elf/ld.so
+ 127093           1920   16720  145733   23945 nptl/libpthread.so
+  30380            988     272   31640    7b98 rt/librt.so

--- sizes-mips-linux-gnu.inline
+++ sizes-mips-linux-gnu.outline
    text           data     bss     dec     hex filename
-1644339          21129   10824 1676292  199404 libc.so
- 173460           4856     264  178580   2b994 elf/ld.so
- 120945           1016    8420  130381   1fd4d nptl/libpthread.so
-  30822            560     192   31574    7b56 rt/librt.so
+1644411          21137   10824 1676372  199454 libc.so
+ 173652           4856     264  178772   2ba54 elf/ld.so
+ 121357           1020    8420  130797   1feed nptl/libpthread.so
+  30830            560     192   31582    7b5e rt/librt.so

The inline __syscall_error is used on C syscall implementations
and a arch-specific syscall_error.c is added to handle the
auto-generated ones.

Checked on mips64-linux-gnu and mips-linux-gnu.
---
 sysdeps/mips/Makefile                         |  5 -
 sysdeps/mips/nptl/Makefile                    |  5 -
 sysdeps/mips/nptl/nptl-sysdep.S               |  2 -
 sysdeps/unix/mips/mips32/sysdep.h             |  5 +-
 sysdeps/unix/mips/mips64/sysdep.h             |  3 +-
 sysdeps/unix/mips/rt-sysdep.S                 |  1 -
 sysdeps/unix/mips/sysdep.S                    | 99 -------------------
 sysdeps/unix/sysv/linux/mips/clone.S          |  1 +
 sysdeps/unix/sysv/linux/mips/getcontext.S     |  1 +
 .../unix/sysv/linux/mips/mips64/n64/ioctl.S   |  3 +-
 sysdeps/unix/sysv/linux/mips/mips64/syscall.S |  3 +-
 sysdeps/unix/sysv/linux/mips/setcontext.S     |  1 +
 sysdeps/unix/sysv/linux/mips/swapcontext.S    |  1 +
 sysdeps/unix/sysv/linux/mips/syscall_error.c  |  3 +
 sysdeps/unix/sysv/linux/mips/vfork.S          |  1 +
 15 files changed, 17 insertions(+), 117 deletions(-)
 delete mode 100644 sysdeps/mips/nptl/nptl-sysdep.S
 delete mode 100644 sysdeps/unix/mips/rt-sysdep.S
 delete mode 100644 sysdeps/unix/mips/sysdep.S
 create mode 100644 sysdeps/unix/sysv/linux/mips/syscall_error.c

diff --git a/sysdeps/mips/Makefile b/sysdeps/mips/Makefile
index 6ad69e9ef9..70c599ec95 100644
--- a/sysdeps/mips/Makefile
+++ b/sysdeps/mips/Makefile
@@ -7,11 +7,6 @@ ifeq ($(subdir),setjmp)
 sysdep_routines += setjmp_aux
 endif
 
-ifeq ($(subdir),rt)
-librt-sysdep_routines += rt-sysdep
-librt-shared-only-routines += rt-sysdep
-endif
-
 ifeq ($(subdir),csu)
 CPPFLAGS-crti.S += $(pic-ccflag)
 CPPFLAGS-crtn.S += $(pic-ccflag)
diff --git a/sysdeps/mips/nptl/Makefile b/sysdeps/mips/nptl/Makefile
index e9d279a530..eb5d51c450 100644
--- a/sysdeps/mips/nptl/Makefile
+++ b/sysdeps/mips/nptl/Makefile
@@ -18,8 +18,3 @@
 ifeq ($(subdir),csu)
 gen-as-const-headers += tcb-offsets.sym
 endif
-
-ifeq ($(subdir),nptl)
-libpthread-sysdep_routines += nptl-sysdep
-libpthread-shared-only-routines += nptl-sysdep
-endif
diff --git a/sysdeps/mips/nptl/nptl-sysdep.S b/sysdeps/mips/nptl/nptl-sysdep.S
deleted file mode 100644
index 3f5c2a364a..0000000000
--- a/sysdeps/mips/nptl/nptl-sysdep.S
+++ /dev/null
@@ -1,2 +0,0 @@
-/* Pull in __syscall_error.  */
-#include <sysdep.S>
diff --git a/sysdeps/unix/mips/mips32/sysdep.h b/sysdeps/unix/mips/mips32/sysdep.h
index b09367347e..8f3d561abf 100644
--- a/sysdeps/unix/mips/mips32/sysdep.h
+++ b/sysdeps/unix/mips/mips32/sysdep.h
@@ -26,7 +26,8 @@
   .align 2;								      \
   .set nomips16;							      \
   cfi_startproc;							      \
-  99: la t9,__syscall_error;						      \
+  99: subu a0, zero, v0;						      \
+  la t9,__syscall_error;						      \
   jr t9;								      \
   cfi_endproc;								      \
   ENTRY(name)								      \
@@ -44,7 +45,7 @@ L(syse1):
   .align 2;								      \
   cfi_startproc;							      \
   99: j __syscall_error;						      \
-  nop;									      \
+   subu a0, zero, v0;							      \
   cfi_endproc;								      \
   ENTRY(name)								      \
   .set noreorder;							      \
diff --git a/sysdeps/unix/mips/mips64/sysdep.h b/sysdeps/unix/mips/mips64/sysdep.h
index fb5f27daf3..ff14bcceec 100644
--- a/sysdeps/unix/mips/mips64/sysdep.h
+++ b/sysdeps/unix/mips/mips64/sysdep.h
@@ -30,6 +30,7 @@
   .set nomips16;							      \
   cfi_startproc;							      \
   99:;									      \
+  dsubu a0, zero, v0;							      \
   .set noat;								      \
   .cpsetup t9, $1, name;						      \
   cfi_register (gp, $1);						      \
@@ -51,7 +52,7 @@ L(syse1):
   .set nomips16;							      \
   cfi_startproc;							      \
   99: j __syscall_error;						      \
-  nop;                                                                        \
+   dsubu a0, zero, v0;							      \
   cfi_endproc;								      \
   ENTRY(name)								      \
   .set noreorder;							      \
diff --git a/sysdeps/unix/mips/rt-sysdep.S b/sysdeps/unix/mips/rt-sysdep.S
deleted file mode 100644
index f966bf1e59..0000000000
--- a/sysdeps/unix/mips/rt-sysdep.S
+++ /dev/null
@@ -1 +0,0 @@
-#include <sysdep.S>
diff --git a/sysdeps/unix/mips/sysdep.S b/sysdeps/unix/mips/sysdep.S
deleted file mode 100644
index 744d1620b3..0000000000
--- a/sysdeps/unix/mips/sysdep.S
+++ /dev/null
@@ -1,99 +0,0 @@
-/* Copyright (C) 1992-2020 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-   Contributed by Brendan Kehoe (brendan@zen.org).
-
-   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 <sysdep.h>
-#include <errno.h>
-#include <sys/asm.h>
-
-	.set	nomips16
-
-#ifdef _LIBC_REENTRANT
-
-LOCALSZ= 3
-FRAMESZ= (((NARGSAVE+LOCALSZ)*SZREG)+ALSZ)&ALMASK
-RAOFF= FRAMESZ-(1*SZREG)
-GPOFF= FRAMESZ-(2*SZREG)
-V0OFF= FRAMESZ-(3*SZREG)
-
-ENTRY(__syscall_error)
-#ifdef __PIC__
-	.set noat
-	SETUP_GPX (AT)
-	.set at
-#endif
-	PTR_SUBU sp, FRAMESZ
-	.set noat
-	SETUP_GPX64(GPOFF,AT)
-	.set at
-#ifdef __PIC__
-	SAVE_GP(GPOFF)
-#endif
-	REG_S	v0, V0OFF(sp)
-	REG_S	ra, RAOFF(sp)
-
-#if defined (EWOULDBLOCK_sys) && EWOULDBLOCK_sys != EAGAIN
-	/* We translate the system's EWOULDBLOCK error into EAGAIN.
-	   The GNU C library always defines EWOULDBLOCK==EAGAIN.
-	   EWOULDBLOCK_sys is the original number.  */
-	bne	v0, EWOULDBLOCK_sys, L(skip)
-	nop
-	li	v0, EAGAIN
-L(skip):
-#endif
-	/* Find our per-thread errno address  */
-	jal	__errno_location
-
-	/* Store the error value.  */
-	REG_L	t0, V0OFF(sp)
-	sw	t0, 0(v0)
-
-	/* And just kick back a -1.  */
-	REG_L	ra, RAOFF(sp)
-	RESTORE_GP64
-	PTR_ADDU sp, FRAMESZ
-	li	v0, -1
-	j	ra
-	END(__syscall_error)
-
-#else /* _LIBC_REENTRANT */
-
-
-ENTRY(__syscall_error)
-#ifdef __PIC__
-	SETUP_GPX (AT)
-#endif
-	SETUP_GPX64 (t9, AT)
-
-#if defined (EWOULDBLOCK_sys) && EWOULDBLOCK_sys != EAGAIN
-	/* We translate the system's EWOULDBLOCK error into EAGAIN.
-	   The GNU C library always defines EWOULDBLOCK==EAGAIN.
-	   EWOULDBLOCK_sys is the original number.  */
-	bne v0, EWOULDBLOCK_sys, L(skip)
-	li v0, EAGAIN
-L(skip):
-#endif
-	/* Store it in errno... */
-	sw v0, errno
-
-	/* And just kick back a -1.  */
-	li v0, -1
-
-	RESTORE_GP64
-	j ra
-	END(__syscall_error)
-#endif  /* _LIBC_REENTRANT  */
diff --git a/sysdeps/unix/sysv/linux/mips/clone.S b/sysdeps/unix/sysv/linux/mips/clone.S
index 6a5ec84870..3dd181b6f9 100644
--- a/sysdeps/unix/sysv/linux/mips/clone.S
+++ b/sysdeps/unix/sysv/linux/mips/clone.S
@@ -102,6 +102,7 @@ NESTED(__clone,4*SZREG,sp)
 	/* Something bad happened -- no child created */
 L(error):
 	cfi_restore_state
+	INT_SUBU	a0, zero, v0
 #ifdef __PIC__
 	PTR_LA		t9,__syscall_error
 	RESTORE_GP64_STACK
diff --git a/sysdeps/unix/sysv/linux/mips/getcontext.S b/sysdeps/unix/sysv/linux/mips/getcontext.S
index 69f62d4a75..edb5063647 100644
--- a/sysdeps/unix/sysv/linux/mips/getcontext.S
+++ b/sysdeps/unix/sysv/linux/mips/getcontext.S
@@ -140,6 +140,7 @@ NESTED (__getcontext, FRAMESZ, ra)
 
 99:
 	cfi_restore_state
+	INT_SUBU a0, zero, v0
 #ifdef __PIC__
 	PTR_LA	t9, JUMPTARGET (__syscall_error)
 	RESTORE_GP64_STACK
diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n64/ioctl.S b/sysdeps/unix/sysv/linux/mips/mips64/n64/ioctl.S
index ed58abe7e9..c911abee2a 100644
--- a/sysdeps/unix/sysv/linux/mips/mips64/n64/ioctl.S
+++ b/sysdeps/unix/sysv/linux/mips/mips64/n64/ioctl.S
@@ -31,7 +31,8 @@ ENTRY (__ioctl)
 	ret
 
 L(error):
-	SETUP_GP64_REG (a0, __ioctl)
+	INT_SUBU a0, zero, v0
+	SETUP_GP64_REG (v0, __ioctl)
 	PTR_LA t9, __syscall_error
 	RESTORE_GP64_REG
 	jr t9
diff --git a/sysdeps/unix/sysv/linux/mips/mips64/syscall.S b/sysdeps/unix/sysv/linux/mips/mips64/syscall.S
index a9baff3c17..8fc6caea71 100644
--- a/sysdeps/unix/sysv/linux/mips/mips64/syscall.S
+++ b/sysdeps/unix/sysv/linux/mips/mips64/syscall.S
@@ -55,7 +55,8 @@ NESTED (syscall, SZREG, ra)
 	ret
 
 L(error):
-	SETUP_GP64_REG (a0, syscall)
+	INT_SUBU a0, zero, v0
+	SETUP_GP64_REG (v0, syscall)
 	PTR_LA t9, __syscall_error
 	RESTORE_GP64_REG
 	jr t9
diff --git a/sysdeps/unix/sysv/linux/mips/setcontext.S b/sysdeps/unix/sysv/linux/mips/setcontext.S
index 3609af7780..cd058c4390 100644
--- a/sysdeps/unix/sysv/linux/mips/setcontext.S
+++ b/sysdeps/unix/sysv/linux/mips/setcontext.S
@@ -149,6 +149,7 @@ NESTED (__setcontext, FRAMESZ, ra)
 	jr	t9
 
 99:
+	INT_SUBU a0, zero, v0
 #ifdef __PIC__
 	PTR_LA	t9, JUMPTARGET (__syscall_error)
 	RESTORE_GP64_STACK
diff --git a/sysdeps/unix/sysv/linux/mips/swapcontext.S b/sysdeps/unix/sysv/linux/mips/swapcontext.S
index bcc66be068..ca3bcddfb7 100644
--- a/sysdeps/unix/sysv/linux/mips/swapcontext.S
+++ b/sysdeps/unix/sysv/linux/mips/swapcontext.S
@@ -200,6 +200,7 @@ NESTED (__swapcontext, FRAMESZ, ra)
 	jr	t9
 
 99:
+	INT_SUBU a0, zero, v0;
 #ifdef __PIC__
 	PTR_LA	t9, JUMPTARGET (__syscall_error)
 	RESTORE_GP64_STACK
diff --git a/sysdeps/unix/sysv/linux/mips/syscall_error.c b/sysdeps/unix/sysv/linux/mips/syscall_error.c
new file mode 100644
index 0000000000..ee8b2e9f0d
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/mips/syscall_error.c
@@ -0,0 +1,3 @@
+/* The auto-generated syscalls call __syscall_error.  */
+#define SYSCALL_ERROR_FUNC
+#include <sysdeps/unix/sysv/linux/syscall_error.c>
diff --git a/sysdeps/unix/sysv/linux/mips/vfork.S b/sysdeps/unix/sysv/linux/mips/vfork.S
index ba3c64ae1e..f579ffe46f 100644
--- a/sysdeps/unix/sysv/linux/mips/vfork.S
+++ b/sysdeps/unix/sysv/linux/mips/vfork.S
@@ -76,6 +76,7 @@ NESTED(__libc_vfork,FRAMESZ,sp)
 	/* Something bad happened -- no child created.  */
 L(error):
 	cfi_restore_state
+	INT_SUBU	a0, zero, v0
 #ifdef __PIC__
 	PTR_LA		t9, __syscall_error
 	RESTORE_GP64_REG
-- 
2.25.1



More information about the Libc-alpha mailing list