Add compat support for s390x

By very popular demand.

While we are here, let's refactor the condition for old_mmap_pgoff into
an arch-specific one, as it is used more than in one place.

* NEWS: Mention this.
* strace.1.in (.SH "MULTIPLE PERSONALITY SUPPORT"): Likewise.
* configure.ac (case "$host_cpu" in) <s390x>: Set arch_m32 to s390, set
cc_flags_m32 to -m31.
(st_MPERS([m32])): Add s390x.
* defs.h [S390X]: Define NEED_UID16_PARSERS.
* linux/s390/arch_sigreturn.c [!S390_FRAME_PTR] (S390_FRAME_PTR): New
macro, define to s390_frame_ptr.
[!SIGNAL_FRAMESIZE] (SIGNAL_FRAMESIZE): New macro, define to
__SIGNAL_FRAMESIZE.
[!PTR_TYPE] (PTR_TYPE): New macro, define to unsigned long.
(arch_sigreturn): Use S390_FRAME_PTR, SIGNAL_FRAMESIZE, and PTR_TYPE
instead of s390_frame_ptr, __SIGNAL_FRAMESIZE, and pointer-sized type,
respectively.
* linux/s390/get_error.c [!ARCH_REGSET] (ARCH_REGSET): New macro, define
* to s390_regset.
(get_error): Use it instead of s390_regset.
* linux/s390/get_scno.c (arch_get_scno): Likewise.
* linux/s390/get_syscall_args.c (get_syscall_args): Likewise.
* linux/s390/set_error.c (arch_set_error, arch_set_success): Likewise.
* linux/s390/set_scno.c (arch_set_scno): Likewise.
* linux/s390x/arch_regs.c (psw_compat_t, s390_compat_regs,
s390x_regs_union, s390_frame_ptr, s390x_frame_ptr, s390x_io): New
variables.
(s390_regset, s390x_regset, ARCH_REGS_FOR_GETREGSET,
ARCH_IOVEC_FOR_GETREGSET, ARCH_PC_REG, ARCH_PERSONALITY_0_IOV_SIZE,
ARCH_PERSONALITY_1_IOV_SIZE): New macros.
* linux/s390x/arch_regs.h (s390_frame_ptr, s390x_frame_ptr): New
prototypes.
* linux/s390x/arch_rt_sigframe.c: Conditionalize on tcp->currpers.
* linux/s390x/arch_sigreturn.c: Likewise.
* linux/s390x/get_error.c: Likewise.
* linux/s390x/get_scno.c: Likewise.
* linux/s390x/get_syscall_args.c: Likewise.
* linux/s390x/set_error.c: Likewise.
* linux/s390x/set_scno.c: Likewise.
* linux/s390x/errnoent1.h: New file.
* linux/s390x/ioctls_arch1.h: Likewise.
* linux/s390x/ioctls_inc1.h: Likewise.
* linux/s390x/signalent1.h: Likewise.
* linux/s390x/syscallent1.h: Likewise.
* Makefile.am (EXTRA_DIST): Add new files added to linux/s390x.
* supported_personalities.h [S390X] (SUPPORTED_PERSONALITIES): Define
to 2.
* tests/strace-V.test: Add s390 to the list of architectures that have
m32 personality.
* linux/s390/arch_defs.h (HAVE_ARCH_OLD_MMAP_PGOFF): New macro.
* linux/s390x/arch_defs.h: Likewise.
* mem.c: Replace #ifdef S390 with #ifdef HAVE_ARCH_OLD_MMAP_PGOFF.
* pathtrace.c: Likewise.
This commit is contained in:
Eugene Syromyatnikov 2018-01-10 20:20:06 +00:00
parent 6850ddbc42
commit d9f6166f0c
31 changed files with 254 additions and 31 deletions

View File

@ -712,15 +712,20 @@ EXTRA_DIST = \
linux/s390x/arch_regs.h \
linux/s390x/arch_rt_sigframe.c \
linux/s390x/arch_sigreturn.c \
linux/s390x/errnoent1.h \
linux/s390x/get_error.c \
linux/s390x/get_scno.c \
linux/s390x/get_syscall_args.c \
linux/s390x/ioctls_arch0.h \
linux/s390x/ioctls_arch1.h \
linux/s390x/ioctls_inc0.h \
linux/s390x/ioctls_inc1.h \
linux/s390x/rt_sigframe.h \
linux/s390x/set_error.c \
linux/s390x/set_scno.c \
linux/s390x/signalent1.h \
linux/s390x/syscallent.h \
linux/s390x/syscallent1.h \
linux/s390x/userent.h \
linux/sh/arch_getrval2.c \
linux/sh/arch_regs.c \

1
NEWS
View File

@ -24,6 +24,7 @@ Noteworthy changes in release ?.?? (????-??-??)
* Updated lists of MSG_*, NT_*, and SHM_* constants.
* Added manual page for the strace-log-merge command.
* Updated lists of ioctl commands from Linux 4.15.
* Implemented biarch support for s390x.
* Implemented an optional support for symbol demangling in strace -k output
(activated by --with-libiberty configure option).
* Information about availability of demangling and reliable personality

View File

@ -145,6 +145,8 @@ s390)
;;
s390x)
arch=s390x
arch_m32=s390
cc_flags_m32=-m31
AC_DEFINE([S390X], 1, [Define for the S390x architecture.])
;;
hppa*|parisc*)
@ -980,7 +982,7 @@ AC_ARG_ENABLE([mpers],
esac],
[enable_mpers=yes])
st_MPERS([m32], [aarch64|powerpc64|riscv|sparc64|tile|x32|x86_64])
st_MPERS([m32], [aarch64|powerpc64|riscv|s390x|sparc64|tile|x32|x86_64])
st_MPERS([mx32], [x86_64])
AX_VALGRIND_DFLT([sgcheck], [off])

2
defs.h
View File

@ -335,7 +335,7 @@ extern const struct xlat whence_codes[];
|| defined(M68K) \
|| defined(MICROBLAZE) \
|| defined(RISCV) \
|| defined(S390) \
|| defined(S390) || defined(S390X) \
|| defined(SH) || defined(SH64) \
|| defined(SPARC) || defined(SPARC64) \
/**/

View File

@ -1 +1,2 @@
#define HAVE_ARCH_OLD_MMAP 1
#define HAVE_ARCH_OLD_MMAP_PGOFF 1

View File

@ -1,11 +1,21 @@
#ifndef S390_FRAME_PTR
# define S390_FRAME_PTR s390_frame_ptr
#endif
#ifndef SIGNAL_FRAMESIZE
# define SIGNAL_FRAMESIZE __SIGNAL_FRAMESIZE
#endif
#ifndef PTR_TYPE
# define PTR_TYPE unsigned long
#endif
static void
arch_sigreturn(struct tcb *tcp)
{
unsigned long mask[NSIG_BYTES / sizeof(long)];
const unsigned long addr = *s390_frame_ptr + __SIGNAL_FRAMESIZE;
PTR_TYPE mask[NSIG_BYTES / sizeof(PTR_TYPE)];
const PTR_TYPE addr = *S390_FRAME_PTR + SIGNAL_FRAMESIZE;
if (umove(tcp, addr, &mask) < 0) {
tprintf("{mask=%#lx}", addr);
tprintf("{mask=%#llx}", zero_extend_signed_to_ull(addr));
} else {
tprintsigmask_addr("{mask=", mask);
tprints("}");

View File

@ -1,12 +1,16 @@
#include "negated_errno.h"
#ifndef ARCH_REGSET
# define ARCH_REGSET s390_regset
#endif
static void
get_error(struct tcb *tcp, const bool check_errno)
{
if (check_errno && is_negated_errno(s390_regset.gprs[2])) {
if (check_errno && is_negated_errno(ARCH_REGSET.gprs[2])) {
tcp->u_rval = -1;
tcp->u_error = -s390_regset.gprs[2];
tcp->u_error = -ARCH_REGSET.gprs[2];
} else {
tcp->u_rval = s390_regset.gprs[2];
tcp->u_rval = ARCH_REGSET.gprs[2];
}
}

View File

@ -1,8 +1,12 @@
#ifndef ARCH_REGSET
# define ARCH_REGSET s390_regset
#endif
/* Return codes: 1 - ok, 0 - ignore, other - error. */
static int
arch_get_scno(struct tcb *tcp)
{
tcp->scno = s390_regset.gprs[2] ?
s390_regset.gprs[2] : s390_regset.gprs[1];
tcp->scno = ARCH_REGSET.gprs[2] ?
ARCH_REGSET.gprs[2] : ARCH_REGSET.gprs[1];
return 1;
}

View File

@ -1,12 +1,16 @@
#ifndef ARCH_REGSET
# define ARCH_REGSET s390_regset
#endif
/* Return -1 on error or 1 on success (never 0!). */
static int
get_syscall_args(struct tcb *tcp)
{
tcp->u_arg[0] = s390_regset.orig_gpr2;
tcp->u_arg[1] = s390_regset.gprs[3];
tcp->u_arg[2] = s390_regset.gprs[4];
tcp->u_arg[3] = s390_regset.gprs[5];
tcp->u_arg[4] = s390_regset.gprs[6];
tcp->u_arg[5] = s390_regset.gprs[7];
tcp->u_arg[0] = ARCH_REGSET.orig_gpr2;
tcp->u_arg[1] = ARCH_REGSET.gprs[3];
tcp->u_arg[2] = ARCH_REGSET.gprs[4];
tcp->u_arg[3] = ARCH_REGSET.gprs[5];
tcp->u_arg[4] = ARCH_REGSET.gprs[6];
tcp->u_arg[5] = ARCH_REGSET.gprs[7];
return 1;
}

View File

@ -1,13 +1,17 @@
#ifndef ARCH_REGSET
# define ARCH_REGSET s390_regset
#endif
static int
arch_set_error(struct tcb *tcp)
{
s390_regset.gprs[2] = -tcp->u_error;
ARCH_REGSET.gprs[2] = -tcp->u_error;
return set_regs(tcp->pid);
}
static int
arch_set_success(struct tcb *tcp)
{
s390_regset.gprs[2] = tcp->u_rval;
ARCH_REGSET.gprs[2] = tcp->u_rval;
return set_regs(tcp->pid);
}

View File

@ -1,6 +1,10 @@
#ifndef ARCH_REGSET
# define ARCH_REGSET s390_regset
#endif
static int
arch_set_scno(struct tcb *tcp, kernel_ulong_t scno)
{
s390_regset.gprs[2] = scno;
ARCH_REGSET.gprs[2] = scno;
return set_regs(tcp->pid);
}

View File

@ -1 +1,2 @@
#define HAVE_ARCH_OLD_MMAP 1
#define HAVE_ARCH_OLD_MMAP_PGOFF 1

View File

@ -1 +1,36 @@
#include "s390/arch_regs.c"
typedef struct {
uint32_t mask;
uint32_t addr;
} ATTRIBUTE_ALIGNED(8) psw_compat_t;
typedef struct {
psw_compat_t psw;
uint32_t gprs[NUM_GPRS];
uint32_t acrs[NUM_ACRS];
uint32_t orig_gpr2;
} s390_compat_regs;
static union {
s390_compat_regs s390_regs;
s390_regs s390x_regs;
} s390x_regs_union;
#define s390_regset s390x_regs_union.s390_regs
#define s390x_regset s390x_regs_union.s390x_regs
uint32_t *const s390_frame_ptr = &s390_regset.gprs[15];
unsigned long *const s390x_frame_ptr = &s390x_regset.gprs[15];
static struct iovec s390x_io = {
.iov_base = &s390x_regs_union,
};
#define ARCH_REGS_FOR_GETREGSET s390x_regs_union
#define ARCH_IOVEC_FOR_GETREGSET s390x_io
#define ARCH_PC_REG \
(s390x_io.iov_len == sizeof(s390_regset) ? \
s390_regset.psw.addr : s390x_regset.psw.addr)
#define ARCH_PERSONALITY_0_IOV_SIZE sizeof(s390x_regset)
#define ARCH_PERSONALITY_1_IOV_SIZE sizeof(s390_regset)

View File

@ -1 +1,2 @@
#include "s390/arch_regs.h"
extern uint32_t *const s390_frame_ptr;
extern unsigned long *const s390x_frame_ptr;

View File

@ -1 +1,4 @@
#include "s390/arch_rt_sigframe.c"
FUNC_GET_RT_SIGFRAME_ADDR
{
return tcp->currpers == 1 ? *s390_frame_ptr : *s390x_frame_ptr;
}

View File

@ -1 +1,27 @@
#include <stdint.h>
#define S390_SIGNAL_FRAMESIZE 96
#define SIGNAL_FRAMESIZE S390_SIGNAL_FRAMESIZE
#define PTR_TYPE uint32_t
#define S390_FRAME_PTR s390_frame_ptr
#define arch_sigreturn s390_arch_sigreturn
#include "s390/arch_sigreturn.c"
#undef arch_sigreturn
#undef S390_FRAME_PTR
#undef PTR_TYPE
#undef SIGNAL_FRAMESIZE
#define S390_FRAME_PTR s390x_frame_ptr
#define arch_sigreturn s390x_arch_sigreturn
#include "s390/arch_sigreturn.c"
#undef arch_sigreturn
static void
arch_sigreturn(struct tcb *tcp)
{
if (tcp->currpers == 1)
s390_arch_sigreturn(tcp);
else
s390x_arch_sigreturn(tcp);
}

1
linux/s390x/errnoent1.h Normal file
View File

@ -0,0 +1 @@
#include "errnoent.h"

View File

@ -1 +1,22 @@
#include "s390/get_error.c"
#include "negated_errno.h"
#define get_error s390_get_error
#define ARCH_REGSET s390_regset
#include "../s390/get_error.c"
#undef ARCH_REGSET
#undef get_error
#define get_error s390x_get_error
#define ARCH_REGSET s390x_regset
#include "../s390/get_error.c"
#undef ARCH_REGSET
#undef get_error
static void
get_error(struct tcb *tcp, const bool check_errno)
{
if (tcp->currpers == 1)
s390_get_error(tcp, check_errno);
else
s390x_get_error(tcp, check_errno);
}

View File

@ -1 +1,20 @@
#include "s390/get_scno.c"
#define arch_get_scno s390_get_scno
#define ARCH_REGSET s390_regset
#include "../s390/get_scno.c"
#undef ARCH_REGSET
#undef arch_get_scno
#define arch_get_scno s390x_get_scno
#define ARCH_REGSET s390x_regset
#include "../s390/get_scno.c"
#undef ARCH_REGSET
#undef arch_get_scno
static int
arch_get_scno(struct tcb *tcp)
{
if (s390x_io.iov_len == sizeof(s390_regset))
return s390_get_scno(tcp);
else
return s390x_get_scno(tcp);
}

View File

@ -1 +1,21 @@
#include "s390/get_syscall_args.c"
#define get_syscall_args s390_get_syscall_args
#define ARCH_REGSET s390_regset
#include "../s390/get_syscall_args.c"
#undef ARCH_REGSET
#undef get_syscall_args
#define get_syscall_args s390x_get_syscall_args
#define ARCH_REGSET s390x_regset
#include "../s390/get_syscall_args.c"
#undef ARCH_REGSET
#undef get_syscall_args
/* Return -1 on error or 1 on success (never 0!). */
static int
get_syscall_args(struct tcb *tcp)
{
if (tcp->currpers == 1)
return s390_get_syscall_args(tcp);
else
return s390x_get_syscall_args(tcp);
}

View File

@ -0,0 +1 @@
#include "s390/ioctls_arch0.h"

View File

@ -0,0 +1 @@
#include "s390/ioctls_inc0.h"

View File

@ -1 +1,33 @@
#include "s390/set_error.c"
#define arch_set_error s390_set_error
#define arch_set_success s390_set_success
#define ARCH_REGSET s390_regset
#include "../s390/set_error.c"
#undef ARCH_REGSET
#undef arch_set_success
#undef arch_set_error
#define arch_set_error s390x_set_error
#define arch_set_success s390x_set_success
#define ARCH_REGSET s390x_regset
#include "../s390/set_error.c"
#undef ARCH_REGSET
#undef arch_set_success
#undef arch_set_error
static int
arch_set_error(struct tcb *tcp)
{
if (tcp->currpers == 1)
return s390_set_error(tcp);
else
return s390x_set_error(tcp);
}
static int
arch_set_success(struct tcb *tcp)
{
if (tcp->currpers == 1)
return s390_set_success(tcp);
else
return s390x_set_success(tcp);
}

View File

@ -1 +1,20 @@
#include "s390/set_scno.c"
#define arch_set_scno s390_set_scno
#define ARCH_REGSET s390_regset
#include "../s390/set_scno.c"
#undef ARCH_REGSET
#undef arch_set_scno
#define arch_set_scno s390x_set_scno
#define ARCH_REGSET s390x_regset
#include "../s390/set_scno.c"
#undef ARCH_REGSET
#undef arch_set_scno
static int
arch_set_scno(struct tcb *tcp, kernel_ulong_t scno)
{
if (tcp->currpers == 1)
return s390_set_scno(tcp, scno);
else
return s390x_set_scno(tcp, scno);
}

1
linux/s390x/signalent1.h Normal file
View File

@ -0,0 +1 @@
#include "signalent.h"

View File

@ -0,0 +1 @@
#include "s390/syscallent.h"

4
mem.c
View File

@ -144,7 +144,7 @@ SYS_FUNC(old_mmap)
return RVAL_DECODED | RVAL_HEX;
}
# ifdef S390
# ifdef HAVE_ARCH_OLD_MMAP_PGOFF
/* Params are pointed to by u_arg[0], offset is in pages */
SYS_FUNC(old_mmap_pgoff)
{
@ -163,7 +163,7 @@ SYS_FUNC(old_mmap_pgoff)
return RVAL_DECODED | RVAL_HEX;
}
# endif /* S390 */
# endif /* HAVE_ARCH_OLD_MMAP_PGOFF */
#endif /* HAVE_ARCH_OLD_MMAP */
/* Params are passed directly, offset is in bytes */

View File

@ -216,7 +216,7 @@ pathtrace_match_set(struct tcb *tcp, struct path_set *set)
#ifdef HAVE_ARCH_OLD_MMAP
case SEN_old_mmap:
# if defined(S390)
# ifdef HAVE_ARCH_OLD_MMAP_PGOFF
case SEN_old_mmap_pgoff:
# endif
{

View File

@ -879,6 +879,7 @@ x86_64 i386, x32 (when built as an x86_64 application); i386 (when built as an x
AArch64 ARM 32-bit EABI
PowerPC 64-bit PowerPC 32-bit
RISC-V 64-bit RISC-V 32-bit
s390x s390
SPARC 64-bit SPARC 32-bit
TILE 64-bit TILE 32-bit
.TE

View File

@ -33,6 +33,7 @@
#elif defined AARCH64 \
|| defined POWERPC64 \
|| defined RISCV \
|| defined S390X \
|| defined SPARC64 \
|| defined TILE \
|| defined X32

View File

@ -48,7 +48,7 @@ x86_64)
option_m32=$(getoption HAVE_M32_MPERS ' m32-mpers' ' no-m32-mpers')
option_mx32=$(getoption HAVE_MX32_MPERS ' mx32-mpers' ' no-mx32-mpers')
;;
aarch64|powerpc64|riscv|sparc64|tile|x32)
aarch64|powerpc64|riscv|s390x|sparc64|tile|x32)
option_m32=$(getoption HAVE_M32_MPERS ' m32-mpers' ' no-m32-mpers')
;;
esac