public inbox for glibc-cvs@sourceware.org
help / color / mirror / Atom feed
* [glibc/azanella/syscall-refactor] x86_64: Remove assembly syscall macros
@ 2020-06-29 21:49 Adhemerval Zanella
0 siblings, 0 replies; only message in thread
From: Adhemerval Zanella @ 2020-06-29 21:49 UTC (permalink / raw)
To: glibc-cvs
https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=2b389b8dd5c768e0e2e07eb6feedb96069acb7c8
commit 2b389b8dd5c768e0e2e07eb6feedb96069acb7c8
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
Date: Fri Jun 19 09:08:41 2020 -0300
x86_64: Remove assembly syscall macros
Diff:
---
sysdeps/unix/sysv/linux/x86_64/clone.S | 16 +--
sysdeps/unix/sysv/linux/x86_64/getcontext.S | 12 +-
sysdeps/unix/sysv/linux/x86_64/setcontext.S | 4 +-
sysdeps/unix/sysv/linux/x86_64/swapcontext.S | 5 +-
sysdeps/unix/sysv/linux/x86_64/syscall.S | 5 +-
sysdeps/unix/sysv/linux/x86_64/sysdep.h | 163 +--------------------------
sysdeps/unix/sysv/linux/x86_64/vfork.S | 47 ++++----
sysdeps/unix/sysv/linux/x86_64/x32/sysdep.h | 21 ----
sysdeps/unix/x86_64/sysdep.S | 49 --------
sysdeps/unix/x86_64/sysdep.h | 34 ------
sysdeps/x86_64/sysdep.h | 8 --
11 files changed, 45 insertions(+), 319 deletions(-)
diff --git a/sysdeps/unix/sysv/linux/x86_64/clone.S b/sysdeps/unix/sysv/linux/x86_64/clone.S
index 5ae90f06d3..29778141a5 100644
--- a/sysdeps/unix/sysv/linux/x86_64/clone.S
+++ b/sysdeps/unix/sysv/linux/x86_64/clone.S
@@ -49,11 +49,10 @@
.text
ENTRY (__clone)
/* Sanity check arguments. */
- movq $-EINVAL,%rax
testq %rdi,%rdi /* no NULL function pointers */
- jz SYSCALL_ERROR_LABEL
+ jz 1f
testq %rsi,%rsi /* no NULL stack pointers */
- jz SYSCALL_ERROR_LABEL
+ jz 1f
/* Insert the argument onto the new stack. */
subq $16,%rsi
@@ -68,7 +67,7 @@ ENTRY (__clone)
movq %r8, %rdx
movq %r9, %r8
mov 8(%rsp), %R10_LP
- movl $SYS_ify(clone),%eax
+ movl $__NR_clone,%eax
/* End FDE now, because in the child the unwind info will be
wrong. */
@@ -76,7 +75,7 @@ ENTRY (__clone)
syscall
testq %rax,%rax
- jl SYSCALL_ERROR_LABEL
+ jl syscall_error
jz L(thread_start)
ret
@@ -95,12 +94,15 @@ L(thread_start):
call *%rax
/* Call exit with return value from function call. */
movq %rax, %rdi
- movl $SYS_ify(exit), %eax
+ movl $__NR_exit, %eax
syscall
cfi_endproc;
cfi_startproc;
-PSEUDO_END (__clone)
+1:
+ movq $-EINVAL, %rdi
+ jmp syscall_error
+END (__clone)
libc_hidden_def (__clone)
weak_alias (__clone, clone)
diff --git a/sysdeps/unix/sysv/linux/x86_64/getcontext.S b/sysdeps/unix/sysv/linux/x86_64/getcontext.S
index debdd891ab..a7c17cc322 100644
--- a/sysdeps/unix/sysv/linux/x86_64/getcontext.S
+++ b/sysdeps/unix/sysv/linux/x86_64/getcontext.S
@@ -118,20 +118,20 @@ L(no_shstk):
rt_sigprocmask (SIG_BLOCK, NULL, set,_NSIG/8). */
leaq oSIGMASK(%rdi), %rdx
xorl %esi,%esi
-#if SIG_BLOCK == 0
+ /* SIG_BLOCK is 0. */
xorl %edi, %edi
-#else
- movl $SIG_BLOCK, %edi
-#endif
movl $_NSIG8,%r10d
movl $__NR_rt_sigprocmask, %eax
syscall
+ /* The rt_sigprocmask is highly unlikely to fail, since HOW is a
+ always valid (SIG_BLOCK) and EFAUT should no happen since
+ an invalid memory would be triggered by the fnstenv. */
cmpq $-4095, %rax /* Check %rax for error. */
- jae SYSCALL_ERROR_LABEL /* Jump to error handler if error. */
+ jae syscall_error
/* All done, return 0 for success. */
xorl %eax, %eax
ret
-PSEUDO_END(__getcontext)
+END(__getcontext)
weak_alias (__getcontext, getcontext)
diff --git a/sysdeps/unix/sysv/linux/x86_64/setcontext.S b/sysdeps/unix/sysv/linux/x86_64/setcontext.S
index 31bbc9dbe4..7eee46e759 100644
--- a/sysdeps/unix/sysv/linux/x86_64/setcontext.S
+++ b/sysdeps/unix/sysv/linux/x86_64/setcontext.S
@@ -51,7 +51,7 @@ ENTRY(__setcontext)
popq %rdx
cfi_adjust_cfa_offset(-8)
cmpq $-4095, %rax /* Check %rax for error. */
- jae SYSCALL_ERROR_LABEL /* Jump to error handler if error. */
+ jae syscall_error /* Jump to error handler if error. */
/* Restore the floating-point context. Not the registers, only the
rest. */
@@ -192,6 +192,6 @@ L(no_shstk):
/* Clear rax to indicate success. */
xorl %eax, %eax
ret
-PSEUDO_END(__setcontext)
+END(__setcontext)
weak_alias (__setcontext, setcontext)
diff --git a/sysdeps/unix/sysv/linux/x86_64/swapcontext.S b/sysdeps/unix/sysv/linux/x86_64/swapcontext.S
index e071ef6347..21d93297d3 100644
--- a/sysdeps/unix/sysv/linux/x86_64/swapcontext.S
+++ b/sysdeps/unix/sysv/linux/x86_64/swapcontext.S
@@ -79,7 +79,7 @@ ENTRY(__swapcontext)
movl $__NR_rt_sigprocmask, %eax
syscall
cmpq $-4095, %rax /* Check %rax for error. */
- jae SYSCALL_ERROR_LABEL /* Jump to error handler if error. */
+ jae syscall_error /* Jump to error handler if error. */
/* Restore destroyed register into RDX. The choice is arbitrary,
but leaving RDI and RSI available for use later can avoid
@@ -246,6 +246,7 @@ L(no_shstk):
/* Clear rax to indicate success. */
xorl %eax, %eax
ret
-PSEUDO_END(__swapcontext)
+
+END(__swapcontext)
weak_alias (__swapcontext, swapcontext)
diff --git a/sysdeps/unix/sysv/linux/x86_64/syscall.S b/sysdeps/unix/sysv/linux/x86_64/syscall.S
index 6c93fc6304..a1ccbcbcc4 100644
--- a/sysdeps/unix/sysv/linux/x86_64/syscall.S
+++ b/sysdeps/unix/sysv/linux/x86_64/syscall.S
@@ -36,7 +36,6 @@ ENTRY (syscall)
movq 8(%rsp),%r9 /* arg6 is on the stack. */
syscall /* Do the system call. */
cmpq $-4095, %rax /* Check %rax for error. */
- jae SYSCALL_ERROR_LABEL /* Jump to error handler if error. */
+ jae syscall_error /* Jump to error handler if error. */
ret /* Return to caller. */
-
-PSEUDO_END (syscall)
+END (syscall)
diff --git a/sysdeps/unix/sysv/linux/x86_64/sysdep.h b/sysdeps/unix/sysv/linux/x86_64/sysdep.h
index a63acea29e..42628c953f 100644
--- a/sysdeps/unix/sysv/linux/x86_64/sysdep.h
+++ b/sysdeps/unix/sysv/linux/x86_64/sysdep.h
@@ -20,141 +20,11 @@
/* There is some commonality. */
#include <sysdeps/unix/sysv/linux/sysdep.h>
-#include <sysdeps/unix/x86_64/sysdep.h>
+#include <sysdeps/x86_64/sysdep.h>
+#include <sysdeps/unix/sysdep.h>
#include <tcb-offsets.h>
-/* Defines RTLD_PRIVATE_ERRNO. */
-#include <dl-sysdep.h>
-
-/* For Linux we can use the system call table in the header file
- /usr/include/asm/unistd.h
- of the kernel. But these symbols do not follow the SYS_* syntax
- so we have to redefine the `SYS_ify' macro here. */
-#undef SYS_ify
-#define SYS_ify(syscall_name) __NR_##syscall_name
-
-#ifdef __ASSEMBLER__
-
-/* Linux uses a negative return value to indicate syscall errors,
- unlike most Unices, which use the condition codes' carry flag.
-
- Since version 2.1 the return value of a system call might be
- negative even if the call succeeded. E.g., the `lseek' system call
- might return a large offset. Therefore we must not anymore test
- for < 0, but test for a real error by making sure the value in %eax
- is a real error number. Linus said he will make sure the no syscall
- returns a value in -1 .. -4095 as a valid result so we can savely
- test with -4095. */
-
-/* We don't want the label for the error handle to be global when we define
- it here. */
-# undef SYSCALL_ERROR_LABEL
-# ifdef PIC
-# undef SYSCALL_ERROR_LABEL
-# define SYSCALL_ERROR_LABEL 0f
-# else
-# undef SYSCALL_ERROR_LABEL
-# define SYSCALL_ERROR_LABEL syscall_error
-# endif
-
-/* PSEUDO and T_PSEUDO macros have 2 extra arguments for unsigned long
- int arguments. */
-# define PSEUDOS_HAVE_ULONG_INDICES 1
-
-# ifndef SYSCALL_ULONG_ARG_1
-# define SYSCALL_ULONG_ARG_1 0
-# define SYSCALL_ULONG_ARG_2 0
-# endif
-
-# undef PSEUDO
-# if SYSCALL_ULONG_ARG_1
-# define PSEUDO(name, syscall_name, args, ulong_arg_1, ulong_arg_2) \
- .text; \
- ENTRY (name) \
- DO_CALL (syscall_name, args, ulong_arg_1, ulong_arg_2); \
- cmpq $-4095, %rax; \
- jae SYSCALL_ERROR_LABEL
-# else
-# define PSEUDO(name, syscall_name, args) \
- .text; \
- ENTRY (name) \
- DO_CALL (syscall_name, args, 0, 0); \
- cmpq $-4095, %rax; \
- jae SYSCALL_ERROR_LABEL
-# endif
-
-# undef PSEUDO_END
-# define PSEUDO_END(name) \
- SYSCALL_ERROR_HANDLER \
- END (name)
-
-# undef PSEUDO_NOERRNO
-# if SYSCALL_ULONG_ARG_1
-# define PSEUDO_NOERRNO(name, syscall_name, args, ulong_arg_1, ulong_arg_2) \
- .text; \
- ENTRY (name) \
- DO_CALL (syscall_name, args, ulong_arg_1, ulong_arg_2)
-# else
-# define PSEUDO_NOERRNO(name, syscall_name, args) \
- .text; \
- ENTRY (name) \
- DO_CALL (syscall_name, args, 0, 0)
-# endif
-
-# undef PSEUDO_END_NOERRNO
-# define PSEUDO_END_NOERRNO(name) \
- END (name)
-
-# define ret_NOERRNO ret
-
-# undef PSEUDO_ERRVAL
-# if SYSCALL_ULONG_ARG_1
-# define PSEUDO_ERRVAL(name, syscall_name, args, ulong_arg_1, ulong_arg_2) \
- .text; \
- ENTRY (name) \
- DO_CALL (syscall_name, args, ulong_arg_1, ulong_arg_2); \
- negq %rax
-# else
-# define PSEUDO_ERRVAL(name, syscall_name, args) \
- .text; \
- ENTRY (name) \
- DO_CALL (syscall_name, args, 0, 0); \
- negq %rax
-# endif
-
-# undef PSEUDO_END_ERRVAL
-# define PSEUDO_END_ERRVAL(name) \
- END (name)
-
-# define ret_ERRVAL ret
-
-# if defined PIC && RTLD_PRIVATE_ERRNO
-# define SYSCALL_SET_ERRNO \
- lea rtld_errno(%rip), %RCX_LP; \
- neg %eax; \
- movl %eax, (%rcx)
-# else
-# if IS_IN (libc)
-# define SYSCALL_ERROR_ERRNO __libc_errno
-# else
-# define SYSCALL_ERROR_ERRNO errno
-# endif
-# define SYSCALL_SET_ERRNO \
- movq SYSCALL_ERROR_ERRNO@GOTTPOFF(%rip), %rcx;\
- neg %eax; \
- movl %eax, %fs:(%rcx);
-# endif
-
-# ifndef PIC
-# define SYSCALL_ERROR_HANDLER /* Nothing here; code in sysdep.S is used. */
-# else
-# define SYSCALL_ERROR_HANDLER \
-0: \
- SYSCALL_SET_ERRNO; \
- or $-1, %RAX_LP; \
- ret;
-# endif /* PIC */
-
+#ifndef __ASSEMBLER__
/* The Linux/x86-64 kernel expects the system call parameters in
registers according to the following table:
@@ -176,7 +46,6 @@
registers and the seventh parameter and later on the stack. The
register use is as follows:
- system call number in the DO_CALL macro
arg 1 rdi
arg 2 rsi
arg 3 rdx
@@ -188,34 +57,8 @@
called the stack is not aligned since the return address has just
been pushed.
-
Syscalls of more than 6 arguments are not supported. */
-# undef DO_CALL
-# define DO_CALL(syscall_name, args, ulong_arg_1, ulong_arg_2) \
- DOARGS_##args \
- ZERO_EXTEND_##ulong_arg_1 \
- ZERO_EXTEND_##ulong_arg_2 \
- movl $SYS_ify (syscall_name), %eax; \
- syscall;
-
-# define DOARGS_0 /* nothing */
-# define DOARGS_1 /* nothing */
-# define DOARGS_2 /* nothing */
-# define DOARGS_3 /* nothing */
-# define DOARGS_4 movq %rcx, %r10;
-# define DOARGS_5 DOARGS_4
-# define DOARGS_6 DOARGS_5
-
-# define ZERO_EXTEND_0 /* nothing */
-# define ZERO_EXTEND_1 /* nothing */
-# define ZERO_EXTEND_2 /* nothing */
-# define ZERO_EXTEND_3 /* nothing */
-# define ZERO_EXTEND_4 /* nothing */
-# define ZERO_EXTEND_5 /* nothing */
-# define ZERO_EXTEND_6 /* nothing */
-
-#else /* !__ASSEMBLER__ */
/* NB: This also works when X is an array. For an array X, type of
(X) - (X) is ptrdiff_t, which is signed, since size of ptrdiff_t
diff --git a/sysdeps/unix/sysv/linux/x86_64/vfork.S b/sysdeps/unix/sysv/linux/x86_64/vfork.S
index 776d2fc610..c05067758c 100644
--- a/sysdeps/unix/sysv/linux/x86_64/vfork.S
+++ b/sysdeps/unix/sysv/linux/x86_64/vfork.S
@@ -16,26 +16,8 @@
<https://www.gnu.org/licenses/>. */
#include <sysdep.h>
-#define _ERRNO_H 1
-#include <bits/errno.h>
#include <tcb-offsets.h>
-#if SHSTK_ENABLED
-/* The shadow stack prevents us from pushing the saved return PC onto
- the stack and returning normally. Instead we pop the shadow stack
- and return directly. This is the safest way to return and ensures
- any stack manipulations done by the vfork'd child doesn't cause the
- parent to terminate when CET is enabled. */
-# undef SYSCALL_ERROR_HANDLER
-# define SYSCALL_ERROR_HANDLER \
-0: \
- SYSCALL_SET_ERRNO; \
- or $-1, %RAX_LP; \
- jmp 1b;
-# undef SYSCALL_ERROR_LABEL
-# define SYSCALL_ERROR_LABEL 0f
-#endif
-
/* Clone the calling process, but without copying the whole address space.
The calling process is suspended until the new process exits or is
replaced by a call to `execve'. Return -1 for errors, 0 to the new process,
@@ -50,7 +32,7 @@ ENTRY (__vfork)
cfi_register(%rip, %rdi)
/* Stuff the syscall number in RAX and enter into the kernel. */
- movl $SYS_ify (vfork), %eax
+ movl $__NR_vfork, %eax
syscall
#if !SHSTK_ENABLED
@@ -60,9 +42,17 @@ ENTRY (__vfork)
#endif
cmpl $-4095, %eax
- jae SYSCALL_ERROR_LABEL /* Branch forward if it failed. */
-
-#if SHSTK_ENABLED
+#if !SHSTK_ENABLED
+ jae syscall_error /* Branch forward if it failed. */
+ /* Normal return. */
+ ret
+#else
+/* The shadow stack prevents us from pushing the saved return PC onto
+ the stack and returning normally. Instead we pop the shadow stack
+ and return directly. This is the safest way to return and ensures
+ any stack manipulations done by the vfork'd child doesn't cause the
+ parent to terminate when CET is enabled. */
+ jae 0f
1:
/* Check if shadow stack is in use. */
xorl %esi, %esi
@@ -81,12 +71,15 @@ L(no_shstk):
/* Push back the return PC. */
pushq %rdi
cfi_adjust_cfa_offset(8)
-#endif
- /* Normal return. */
- ret
-
-PSEUDO_END (__vfork)
+0:
+ movq SYSCALL_ERROR_ERRNO@GOTTPOFF(%rip), %rcx
+ neg %eax
+ movl %eax, %fs:(%rcx)
+ or $-1, %RAX_LP
+ jmp 1b
+#endif
+END (__vfork)
libc_hidden_def (__vfork)
weak_alias (__vfork, vfork)
diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/sysdep.h b/sysdeps/unix/sysv/linux/x86_64/x32/sysdep.h
index 7ae3b6291a..6988c8d060 100644
--- a/sysdeps/unix/sysv/linux/x86_64/x32/sysdep.h
+++ b/sysdeps/unix/sysv/linux/x86_64/x32/sysdep.h
@@ -47,25 +47,4 @@ typedef long long int __syscall_arg_t;
#undef LO_HI_LONG
#define LO_HI_LONG(val) (val)
-#ifdef __ASSEMBLER__
-/* Zero-extend 32-bit unsigned long int arguments to 64 bits. */
-# undef ZERO_EXTEND_1
-# define ZERO_EXTEND_1 movl %edi, %edi;
-# undef ZERO_EXTEND_2
-# define ZERO_EXTEND_2 movl %esi, %esi;
-# undef ZERO_EXTEND_3
-# define ZERO_EXTEND_3 movl %edx, %edx;
-# if SYSCALL_ULONG_ARG_1 == 4 || SYSCALL_ULONG_ARG_2 == 4
-# undef DOARGS_4
-# define DOARGS_4 movl %ecx, %r10d;
-# else
-# undef ZERO_EXTEND_4
-# define ZERO_EXTEND_4 movl %r10d, %r10d;
-# endif
-# undef ZERO_EXTEND_5
-# define ZERO_EXTEND_5 movl %r8d, %r8d;
-# undef ZERO_EXTEND_6
-# define ZERO_EXTEND_6 movl %r9d, %r9d;
-#endif /* __ASSEMBLER__ */
-
#endif /* linux/x86_64/x32/sysdep.h */
diff --git a/sysdeps/unix/x86_64/sysdep.S b/sysdeps/unix/x86_64/sysdep.S
deleted file mode 100644
index 2278fce9e4..0000000000
--- a/sysdeps/unix/x86_64/sysdep.S
+++ /dev/null
@@ -1,49 +0,0 @@
-/* Copyright (C) 2001-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 <sysdep.h>
-#include <errno.h>
-#include <tls.h>
-
-#if IS_IN (rtld)
-# include <dl-sysdep.h> /* Defines RTLD_PRIVATE_ERRNO. */
-#endif
-
-.globl C_SYMBOL_NAME(errno)
-.globl syscall_error
-
-__syscall_error:
-#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. */
- cmp $EWOULDBLOCK_sys, %RAX_LP /* Is it the old EWOULDBLOCK? */
- jne notb /* Branch if not. */
- movl $EAGAIN, %eax /* Yes; translate it to EAGAIN. */
-notb:
-#endif
-#ifdef PIC
- movq C_SYMBOL_NAME(errno@GOTTPOFF)(%rip), %rcx
- movl %eax, %fs:0(%rcx)
-#else
- movl %eax, %fs:C_SYMBOL_NAME(errno@TPOFF)
-#endif
- or $-1, %RAX_LP
- ret
-
-#undef __syscall_error
-END (__syscall_error)
diff --git a/sysdeps/unix/x86_64/sysdep.h b/sysdeps/unix/x86_64/sysdep.h
deleted file mode 100644
index c549dce4db..0000000000
--- a/sysdeps/unix/x86_64/sysdep.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/* Copyright (C) 1991-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 <sysdeps/unix/sysdep.h>
-#include <sysdeps/x86_64/sysdep.h>
-
-#ifdef __ASSEMBLER__
-
-/* This is defined as a separate macro so that other sysdep.h files
- can include this one and then redefine DO_CALL. */
-
-#define DO_CALL(syscall_name, args) \
- lea SYS_ify (syscall_name), %rax; \
- syscall
-
-#define r0 %rax /* Normal return-value register. */
-#define r1 %rbx /* Secondary return-value register. */
-#define MOVE(x,y) movq x, y
-
-#endif /* __ASSEMBLER__ */
diff --git a/sysdeps/x86_64/sysdep.h b/sysdeps/x86_64/sysdep.h
index 0b73674f68..0b616a62a2 100644
--- a/sysdeps/x86_64/sysdep.h
+++ b/sysdeps/x86_64/sysdep.h
@@ -48,14 +48,6 @@
#define CALL_MCOUNT /* Do nothing. */
#endif
-#define PSEUDO(name, syscall_name, args) \
-lose: \
- jmp JUMPTARGET(syscall_error) \
- .globl syscall_error; \
- ENTRY (name) \
- DO_CALL (syscall_name, args); \
- jb lose
-
#undef JUMPTARGET
#ifdef SHARED
# ifdef BIND_NOW
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2020-06-29 21:49 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-06-29 21:49 [glibc/azanella/syscall-refactor] x86_64: Remove assembly syscall macros Adhemerval Zanella
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).