2021-01-02 19:32:25 +00:00
|
|
|
/* Copyright (C) 2012-2021 Free Software Foundation, Inc.
|
2012-05-21 21:50:21 +00:00
|
|
|
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
|
Prefer https to http for gnu.org and fsf.org URLs
Also, change sources.redhat.com to sourceware.org.
This patch was automatically generated by running the following shell
script, which uses GNU sed, and which avoids modifying files imported
from upstream:
sed -ri '
s,(http|ftp)(://(.*\.)?(gnu|fsf|sourceware)\.org($|[^.]|\.[^a-z])),https\2,g
s,(http|ftp)(://(.*\.)?)sources\.redhat\.com($|[^.]|\.[^a-z]),https\2sourceware.org\4,g
' \
$(find $(git ls-files) -prune -type f \
! -name '*.po' \
! -name 'ChangeLog*' \
! -path COPYING ! -path COPYING.LIB \
! -path manual/fdl-1.3.texi ! -path manual/lgpl-2.1.texi \
! -path manual/texinfo.tex ! -path scripts/config.guess \
! -path scripts/config.sub ! -path scripts/install-sh \
! -path scripts/mkinstalldirs ! -path scripts/move-if-change \
! -path INSTALL ! -path locale/programs/charmap-kw.h \
! -path po/libc.pot ! -path sysdeps/gnu/errlist.c \
! '(' -name configure \
-execdir test -f configure.ac -o -f configure.in ';' ')' \
! '(' -name preconfigure \
-execdir test -f preconfigure.ac ';' ')' \
-print)
and then by running 'make dist-prepare' to regenerate files built
from the altered files, and then executing the following to cleanup:
chmod a+x sysdeps/unix/sysv/linux/riscv/configure
# Omit irrelevant whitespace and comment-only changes,
# perhaps from a slightly-different Autoconf version.
git checkout -f \
sysdeps/csky/configure \
sysdeps/hppa/configure \
sysdeps/riscv/configure \
sysdeps/unix/sysv/linux/csky/configure
# Omit changes that caused a pre-commit check to fail like this:
# remote: *** error: sysdeps/powerpc/powerpc64/ppc-mcount.S: trailing lines
git checkout -f \
sysdeps/powerpc/powerpc64/ppc-mcount.S \
sysdeps/unix/sysv/linux/s390/s390-64/syscall.S
# Omit change that caused a pre-commit check to fail like this:
# remote: *** error: sysdeps/sparc/sparc64/multiarch/memcpy-ultra3.S: last line does not end in newline
git checkout -f sysdeps/sparc/sparc64/multiarch/memcpy-ultra3.S
2019-09-07 05:40:42 +00:00
|
|
|
<https://www.gnu.org/licenses/>. */
|
2012-05-21 21:50:21 +00:00
|
|
|
|
|
|
|
#ifndef _LINUX_X32_SYSDEP_H
|
|
|
|
#define _LINUX_X32_SYSDEP_H 1
|
|
|
|
|
|
|
|
/* There is some commonality. */
|
|
|
|
#include <sysdeps/unix/sysv/linux/x86_64/sysdep.h>
|
|
|
|
#include <sysdeps/x86_64/x32/sysdep.h>
|
|
|
|
|
x86-64: Update LO_HI_LONG for p{readv,writev}{64}v2
The kernel interface for p{readv,writev}{64}v is
(unsigned long fd, {const }struct iovec *iov, unsigned long vlen,
unsigned long pos_l, unsigned long pos_h)
Except for targets which define __ARCH_WANT_COMPAT_SYS_PREADV64 and
__ARCH_WANT_COMPAT_SYS_PWRITEV64,
(unsigned long fd, {const }struct iovec *iov, unsigned long vlen,
off64_t pos)
is used for p{readv,writev}{64}v. X32 is the only such target. The
LO_HI_LONG macro is used to pass offset to the pos_l and pos_h pair.
Since pos_h is ignored when size of offset == sizeof of pos_l, x86-64
has
#define LO_HI_LONG(val) (val)
But the kernel interface for p{readv,writev}{64}v2 is
(unsigned long fd, {const }struct iovec *iov, unsigned long vlen,
unsigned long pos_l, unsigned long pos_h, int flags)
Except for targets which define __ARCH_WANT_COMPAT_SYS_PREADV64V2 and
__ARCH_WANT_COMPAT_SYS_PWRITEV64V2,
(unsigned long fd, {const }struct iovec *iov, unsigned long vlen,
off64_t pos, int flags)
is used for p{readv,writev}{64}v2. X32 is the only such target. Update
x86-64 LO_HI_LONG to pass 0 as the high part of the offset argument for
p{readv,writev}{64}v2 and define a different LO_HI_LONG for x32 to only
pass one argument for offset.
Tested on x32 and x86-64.
* sysdeps/unix/sysv/linux/x86_64/sysdep.h (LO_HI_LONG): Pass
0 as the high part of offset.
* sysdeps/unix/sysv/linux/x86_64/x32/sysdep.h (LO_HI_LONG): New.
2017-06-05 14:21:44 +00:00
|
|
|
/* How to pass the off{64}_t argument on p{readv,writev}{64}. */
|
|
|
|
#undef LO_HI_LONG
|
|
|
|
#define LO_HI_LONG(val) (val)
|
|
|
|
|
2020-04-29 12:35:34 +00:00
|
|
|
#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;
|
|
|
|
#else /* !__ASSEMBLER__ */
|
x32: Properly pass long to syscall [BZ #25810]
X32 has 32-bit long and pointer with 64-bit off_t. Since x32 psABI
requires that pointers passed in registers must be zero-extended to
64bit, x32 can share many syscall interfaces with LP64. When a LP64
syscall with long and unsigned long arguments is used for x32, these
arguments must be properly extended to 64-bit. Otherwise if the upper
32 bits of the register have undefined value, such a syscall will be
rejected by kernel.
Enforce zero-extension for pointers and array system call arguments.
For integer types, extend to int64_t (the full register) using a
regular cast, resulting in zero or sign extension based on the
signedness of the original type.
For
void *mmap(void *addr, size_t length, int prot, int flags,
int fd, off_t offset);
we now generate
0: 41 f7 c1 ff 0f 00 00 test $0xfff,%r9d
7: 75 1f jne 28 <__mmap64+0x28>
9: 48 63 d2 movslq %edx,%rdx
c: 89 f6 mov %esi,%esi
e: 4d 63 c0 movslq %r8d,%r8
11: 4c 63 d1 movslq %ecx,%r10
14: b8 09 00 00 40 mov $0x40000009,%eax
19: 0f 05 syscall
That is
1. addr is unchanged.
2. length is zero-extend to 64 bits.
3. prot is sign-extend to 64 bits.
4. flags is sign-extend to 64 bits.
5. fd is sign-extend to 64 bits.
6. offset is unchanged.
For int arguments, since kernel uses only the lower 32 bits and ignores
the upper 32 bits in 64-bit registers, these work correctly.
Tested on x86-64 and x32. There are no code changes on x86-64.
2020-04-13 17:31:26 +00:00
|
|
|
# undef ARGIFY
|
|
|
|
/* Enforce zero-extension for pointers and array system call arguments.
|
|
|
|
For integer types, extend to int64_t (the full register) using a
|
|
|
|
regular cast, resulting in zero or sign extension based on the
|
|
|
|
signedness of the original type. */
|
|
|
|
# define ARGIFY(X) \
|
|
|
|
({ \
|
|
|
|
_Pragma ("GCC diagnostic push"); \
|
|
|
|
_Pragma ("GCC diagnostic ignored \"-Wpointer-to-int-cast\""); \
|
|
|
|
(__builtin_classify_type (X) == 5 \
|
|
|
|
? (uintptr_t) (X) : (int64_t) (X)); \
|
|
|
|
_Pragma ("GCC diagnostic pop"); \
|
|
|
|
})
|
|
|
|
#endif /* __ASSEMBLER__ */
|
|
|
|
|
2012-05-21 21:50:21 +00:00
|
|
|
#endif /* linux/x86_64/x32/sysdep.h */
|