Follow @Openwall on Twitter for new release announcements and other news
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date: Mon, 25 Jul 2016 22:53:00 -0500
From: Bobby Bingham <koorogi@...rogi.info>
To: musl@...ts.openwall.com
Subject: [PATCH 3/3] add s390x port

---
 arch/s390x/atomic_arch.h             |  30 ++++
 arch/s390x/bits/alltypes.h.in        |  26 +++
 arch/s390x/bits/endian.h             |   1 +
 arch/s390x/bits/fcntl.h              |  40 +++++
 arch/s390x/bits/fenv.h               |  17 ++
 arch/s390x/bits/float.h              |  16 ++
 arch/s390x/bits/ioctl.h              | 195 +++++++++++++++++++++
 arch/s390x/bits/ipc.h                |  14 ++
 arch/s390x/bits/limits.h             |   8 +
 arch/s390x/bits/msg.h                |  12 ++
 arch/s390x/bits/posix.h              |   2 +
 arch/s390x/bits/reg.h                |   2 +
 arch/s390x/bits/sem.h                |   7 +
 arch/s390x/bits/setjmp.h             |   1 +
 arch/s390x/bits/shm.h                |  25 +++
 arch/s390x/bits/signal.h             | 106 ++++++++++++
 arch/s390x/bits/socket.h             |  44 +++++
 arch/s390x/bits/stat.h               |  16 ++
 arch/s390x/bits/statfs.h             |   7 +
 arch/s390x/bits/stdint.h             |  20 +++
 arch/s390x/bits/syscall.h.in         | 323 +++++++++++++++++++++++++++++++++++
 arch/s390x/bits/user.h               |  62 +++++++
 arch/s390x/crt_arch.h                |  17 ++
 arch/s390x/pthread_arch.h            |  14 ++
 arch/s390x/reloc.h                   |  17 ++
 arch/s390x/syscall_arch.h            |  76 +++++++++
 configure                            |   1 +
 crt/s390x/crti.s                     |  17 ++
 crt/s390x/crtn.s                     |   9 +
 src/fenv/s390x/fenv.c                |  55 ++++++
 src/internal/s390x/syscall.s         |  15 ++
 src/process/s390x/vfork.s            |   8 +
 src/setjmp/s390x/longjmp.s           |  23 +++
 src/setjmp/s390x/setjmp.s            |  25 +++
 src/signal/s390x/restore.s           |   9 +
 src/signal/s390x/sigsetjmp.s         |  23 +++
 src/thread/s390x/__set_thread_area.s |   9 +
 src/thread/s390x/__tls_get_offset.s  |  17 ++
 src/thread/s390x/__unmapself.s       |   6 +
 src/thread/s390x/clone.s             |  47 +++++
 src/thread/s390x/syscall_cp.s        |  32 ++++
 41 files changed, 1394 insertions(+)
 create mode 100644 arch/s390x/atomic_arch.h
 create mode 100644 arch/s390x/bits/alltypes.h.in
 create mode 100644 arch/s390x/bits/endian.h
 create mode 100644 arch/s390x/bits/fcntl.h
 create mode 100644 arch/s390x/bits/fenv.h
 create mode 100644 arch/s390x/bits/float.h
 create mode 100644 arch/s390x/bits/ioctl.h
 create mode 100644 arch/s390x/bits/ipc.h
 create mode 100644 arch/s390x/bits/limits.h
 create mode 100644 arch/s390x/bits/msg.h
 create mode 100644 arch/s390x/bits/posix.h
 create mode 100644 arch/s390x/bits/reg.h
 create mode 100644 arch/s390x/bits/sem.h
 create mode 100644 arch/s390x/bits/setjmp.h
 create mode 100644 arch/s390x/bits/shm.h
 create mode 100644 arch/s390x/bits/signal.h
 create mode 100644 arch/s390x/bits/socket.h
 create mode 100644 arch/s390x/bits/stat.h
 create mode 100644 arch/s390x/bits/statfs.h
 create mode 100644 arch/s390x/bits/stdint.h
 create mode 100644 arch/s390x/bits/syscall.h.in
 create mode 100644 arch/s390x/bits/user.h
 create mode 100644 arch/s390x/crt_arch.h
 create mode 100644 arch/s390x/pthread_arch.h
 create mode 100644 arch/s390x/reloc.h
 create mode 100644 arch/s390x/syscall_arch.h
 create mode 100644 crt/s390x/crti.s
 create mode 100644 crt/s390x/crtn.s
 create mode 100644 src/fenv/s390x/fenv.c
 create mode 100644 src/internal/s390x/syscall.s
 create mode 100644 src/process/s390x/vfork.s
 create mode 100644 src/setjmp/s390x/longjmp.s
 create mode 100644 src/setjmp/s390x/setjmp.s
 create mode 100644 src/signal/s390x/restore.s
 create mode 100644 src/signal/s390x/sigsetjmp.s
 create mode 100644 src/thread/s390x/__set_thread_area.s
 create mode 100644 src/thread/s390x/__tls_get_offset.s
 create mode 100644 src/thread/s390x/__unmapself.s
 create mode 100644 src/thread/s390x/clone.s
 create mode 100644 src/thread/s390x/syscall_cp.s

diff --git a/arch/s390x/atomic_arch.h b/arch/s390x/atomic_arch.h
new file mode 100644
index 0000000..9b0e1df
--- /dev/null
+++ b/arch/s390x/atomic_arch.h
@@ -0,0 +1,30 @@
+#define a_cas a_cas
+static inline int a_cas(volatile int *p, int t, int s)
+{
+	__asm__ __volatile__ (
+		"cs %0, %2, %1"
+		: "+d"(t), "+Q"(*p) : "d"(s) : "memory", "cc");
+	return t;
+}
+
+#define a_cas_p a_cas_p
+static inline void *a_cas_p(volatile void *p, void *t, void *s)
+{
+	__asm__ __volatile__ (
+		"csg %0, %2, %1"
+		: "+d"(t), "+Q"(*(void *volatile *)p) : "d"(s)
+		: "memory", "cc");
+	return t;
+}
+
+#define a_barrier a_barrier
+static inline void a_barrier()
+{
+	__asm__ __volatile__ ("bcr 15,0" : : : "memory");
+}
+
+#define a_crash a_crash
+static inline void a_crash()
+{
+	__asm__ __volatile__ (".insn e,0");
+}
diff --git a/arch/s390x/bits/alltypes.h.in b/arch/s390x/bits/alltypes.h.in
new file mode 100644
index 0000000..1a83846
--- /dev/null
+++ b/arch/s390x/bits/alltypes.h.in
@@ -0,0 +1,26 @@
+#define _Addr long
+#define _Int64 long
+#define _Reg long
+
+TYPEDEF __builtin_va_list va_list;
+TYPEDEF __builtin_va_list __isoc_va_list;
+
+#ifndef __cplusplus
+TYPEDEF int wchar_t;
+#endif
+
+TYPEDEF double float_t;
+TYPEDEF double double_t;
+
+TYPEDEF struct { long long __ll; long double __ld; } max_align_t;
+
+TYPEDEF long time_t;
+TYPEDEF long suseconds_t;
+
+TYPEDEF struct { union { int __i[14]; volatile int __vi[14]; unsigned long __s[7]; } __u; } pthread_attr_t;
+TYPEDEF struct { union { int __i[10]; volatile int __vi[10]; volatile void *volatile __p[5]; } __u; } pthread_mutex_t;
+TYPEDEF struct { union { int __i[10]; volatile int __vi[10]; volatile void *volatile __p[5]; } __u; } mtx_t;
+TYPEDEF struct { union { int __i[12]; volatile int __vi[12]; void *__p[6]; } __u; } pthread_cond_t;
+TYPEDEF struct { union { int __i[12]; volatile int __vi[12]; void *__p[6]; } __u; } cnd_t;
+TYPEDEF struct { union { int __i[14]; volatile int __vi[14]; void *__p[7]; } __u; } pthread_rwlock_t;
+TYPEDEF struct { union { int __i[8]; volatile int __vi[8]; void *__p[4]; } __u; } pthread_barrier_t;
diff --git a/arch/s390x/bits/endian.h b/arch/s390x/bits/endian.h
new file mode 100644
index 0000000..ef074b7
--- /dev/null
+++ b/arch/s390x/bits/endian.h
@@ -0,0 +1 @@
+#define __BYTE_ORDER __BIG_ENDIAN
diff --git a/arch/s390x/bits/fcntl.h b/arch/s390x/bits/fcntl.h
new file mode 100644
index 0000000..1eca6ba
--- /dev/null
+++ b/arch/s390x/bits/fcntl.h
@@ -0,0 +1,40 @@
+#define O_CREAT        0100
+#define O_EXCL         0200
+#define O_NOCTTY       0400
+#define O_TRUNC       01000
+#define O_APPEND      02000
+#define O_NONBLOCK    04000
+#define O_DSYNC      010000
+#define O_SYNC     04010000
+#define O_RSYNC    04010000
+#define O_DIRECTORY 0200000
+#define O_NOFOLLOW  0400000
+#define O_CLOEXEC  02000000
+
+#define O_ASYNC      020000
+#define O_DIRECT     040000
+#define O_LARGEFILE 0100000
+#define O_NOATIME  01000000
+#define O_PATH    010000000
+#define O_TMPFILE 020200000
+#define O_NDELAY O_NONBLOCK
+
+#define F_DUPFD  0
+#define F_GETFD  1
+#define F_SETFD  2
+#define F_GETFL  3
+#define F_SETFL  4
+
+#define F_GETLK  5
+#define F_SETLK  6
+#define F_SETLKW 7
+
+#define F_SETOWN 8
+#define F_GETOWN 9
+#define F_SETSIG 10
+#define F_GETSIG 11
+
+#define F_SETOWN_EX 15
+#define F_GETOWN_EX 16
+
+#define F_GETOWNER_UIDS 17
diff --git a/arch/s390x/bits/fenv.h b/arch/s390x/bits/fenv.h
new file mode 100644
index 0000000..773dad9
--- /dev/null
+++ b/arch/s390x/bits/fenv.h
@@ -0,0 +1,17 @@
+#define FE_TONEAREST	0
+#define FE_TOWARDZERO	1
+#define FE_UPWARD	2
+#define FE_DOWNWARD	3
+
+#define FE_INEXACT	0x00080000
+#define FE_UNDERFLOW	0x00100000
+#define FE_OVERFLOW	0x00200000
+#define FE_DIVBYZERO	0x00400000
+#define FE_INVALID	0x00800000
+
+#define FE_ALL_EXCEPT	0x00f80000
+
+typedef unsigned fexcept_t;
+typedef unsigned fenv_t;
+
+#define FE_DFL_ENV ((const fenv_t *)-1)
diff --git a/arch/s390x/bits/float.h b/arch/s390x/bits/float.h
new file mode 100644
index 0000000..90b73be
--- /dev/null
+++ b/arch/s390x/bits/float.h
@@ -0,0 +1,16 @@
+#define FLT_EVAL_METHOD 1
+
+#define LDBL_TRUE_MIN 6.47517511943802511092443895822764655e-4966L
+#define LDBL_MIN 3.36210314311209350626267781732175260e-4932L
+#define LDBL_MAX 1.18973149535723176508575932662800702e+4932L
+#define LDBL_EPSILON 1.92592994438723585305597794258492732e-34L
+
+#define LDBL_MANT_DIG 113
+#define LDBL_MIN_EXP (-16381)
+#define LDBL_MAX_EXP 16384
+
+#define LDBL_DIG 33
+#define LDBL_MIN_10_EXP (-4931)
+#define LDBL_MAX_10_EXP 4932
+
+#define DECIMAL_DIG 36
diff --git a/arch/s390x/bits/ioctl.h b/arch/s390x/bits/ioctl.h
new file mode 100644
index 0000000..11196e1
--- /dev/null
+++ b/arch/s390x/bits/ioctl.h
@@ -0,0 +1,195 @@
+#define _IOC(a,b,c,d) ( ((a)<<30) | ((b)<<8) | (c) | ((d)<<16) )
+#define _IOC_NONE  0U
+#define _IOC_WRITE 1U
+#define _IOC_READ  2U
+
+#define _IO(a,b) _IOC(_IOC_NONE,(a),(b),0)
+#define _IOW(a,b,c) _IOC(_IOC_WRITE,(a),(b),sizeof(c))
+#define _IOR(a,b,c) _IOC(_IOC_READ,(a),(b),sizeof(c))
+#define _IOWR(a,b,c) _IOC(_IOC_READ|_IOC_WRITE,(a),(b),sizeof(c))
+
+#define TCGETS		0x5401
+#define TCSETS		0x5402
+#define TCSETSW		0x5403
+#define TCSETSF		0x5404
+#define TCGETA		0x5405
+#define TCSETA		0x5406
+#define TCSETAW		0x5407
+#define TCSETAF		0x5408
+#define TCSBRK		0x5409
+#define TCXONC		0x540A
+#define TCFLSH		0x540B
+#define TIOCEXCL	0x540C
+#define TIOCNXCL	0x540D
+#define TIOCSCTTY	0x540E
+#define TIOCGPGRP	0x540F
+#define TIOCSPGRP	0x5410
+#define TIOCOUTQ	0x5411
+#define TIOCSTI		0x5412
+#define TIOCGWINSZ	0x5413
+#define TIOCSWINSZ	0x5414
+#define TIOCMGET	0x5415
+#define TIOCMBIS	0x5416
+#define TIOCMBIC	0x5417
+#define TIOCMSET	0x5418
+#define TIOCGSOFTCAR	0x5419
+#define TIOCSSOFTCAR	0x541A
+#define FIONREAD	0x541B
+#define TIOCINQ		FIONREAD
+#define TIOCLINUX	0x541C
+#define TIOCCONS	0x541D
+#define TIOCGSERIAL	0x541E
+#define TIOCSSERIAL	0x541F
+#define TIOCPKT		0x5420
+#define FIONBIO		0x5421
+#define TIOCNOTTY	0x5422
+#define TIOCSETD	0x5423
+#define TIOCGETD	0x5424
+#define TCSBRKP		0x5425
+#define TIOCTTYGSTRUCT	0x5426
+#define TIOCSBRK	0x5427
+#define TIOCCBRK	0x5428
+#define TIOCGSID	0x5429
+#define TIOCGPTN	0x80045430
+#define TIOCSPTLCK	0x40045431
+#define TCGETX		0x5432
+#define TCSETX		0x5433
+#define TCSETXF		0x5434
+#define TCSETXW		0x5435
+
+#define FIONCLEX	0x5450
+#define FIOCLEX		0x5451
+#define FIOASYNC	0x5452
+#define TIOCSERCONFIG	0x5453
+#define TIOCSERGWILD	0x5454
+#define TIOCSERSWILD	0x5455
+#define TIOCGLCKTRMIOS	0x5456
+#define TIOCSLCKTRMIOS	0x5457
+#define TIOCSERGSTRUCT	0x5458
+#define TIOCSERGETLSR   0x5459
+#define TIOCSERGETMULTI 0x545A
+#define TIOCSERSETMULTI 0x545B
+
+#define TIOCMIWAIT	0x545C
+#define TIOCGICOUNT	0x545D
+#define FIOQSIZE	0x545E
+
+#define TIOCPKT_DATA		 0
+#define TIOCPKT_FLUSHREAD	 1
+#define TIOCPKT_FLUSHWRITE	 2
+#define TIOCPKT_STOP		 4
+#define TIOCPKT_START		 8
+#define TIOCPKT_NOSTOP		16
+#define TIOCPKT_DOSTOP		32
+#define TIOCPKT_IOCTL		64
+
+#define TIOCSER_TEMT    0x01
+
+struct winsize {
+	unsigned short ws_row;
+	unsigned short ws_col;
+	unsigned short ws_xpixel;
+	unsigned short ws_ypixel;
+};
+
+#define TIOCM_LE        0x001
+#define TIOCM_DTR       0x002
+#define TIOCM_RTS       0x004
+#define TIOCM_ST        0x008
+#define TIOCM_SR        0x010
+#define TIOCM_CTS       0x020
+#define TIOCM_CAR       0x040
+#define TIOCM_RNG       0x080
+#define TIOCM_DSR       0x100
+#define TIOCM_CD        TIOCM_CAR
+#define TIOCM_RI        TIOCM_RNG
+#define TIOCM_OUT1      0x2000
+#define TIOCM_OUT2      0x4000
+#define TIOCM_LOOP      0x8000
+#define TIOCM_MODEM_BITS TIOCM_OUT2
+
+#define N_TTY           0
+#define N_SLIP          1
+#define N_MOUSE         2
+#define N_PPP           3
+#define N_STRIP         4
+#define N_AX25          5
+#define N_X25           6
+#define N_6PACK         7
+#define N_MASC          8
+#define N_R3964         9
+#define N_PROFIBUS_FDL  10
+#define N_IRDA          11
+#define N_SMSBLOCK      12
+#define N_HDLC          13
+#define N_SYNC_PPP      14
+#define N_HCI           15
+
+#define FIOSETOWN       0x8901
+#define SIOCSPGRP       0x8902
+#define FIOGETOWN       0x8903
+#define SIOCGPGRP       0x8904
+#define SIOCATMARK      0x8905
+#define SIOCGSTAMP      0x8906
+
+#define SIOCADDRT       0x890B
+#define SIOCDELRT       0x890C
+#define SIOCRTMSG       0x890D
+
+#define SIOCGIFNAME     0x8910
+#define SIOCSIFLINK     0x8911
+#define SIOCGIFCONF     0x8912
+#define SIOCGIFFLAGS    0x8913
+#define SIOCSIFFLAGS    0x8914
+#define SIOCGIFADDR     0x8915
+#define SIOCSIFADDR     0x8916
+#define SIOCGIFDSTADDR  0x8917
+#define SIOCSIFDSTADDR  0x8918
+#define SIOCGIFBRDADDR  0x8919
+#define SIOCSIFBRDADDR  0x891a
+#define SIOCGIFNETMASK  0x891b
+#define SIOCSIFNETMASK  0x891c
+#define SIOCGIFMETRIC   0x891d
+#define SIOCSIFMETRIC   0x891e
+#define SIOCGIFMEM      0x891f
+#define SIOCSIFMEM      0x8920
+#define SIOCGIFMTU      0x8921
+#define SIOCSIFMTU      0x8922
+#define SIOCSIFHWADDR   0x8924
+#define SIOCGIFENCAP    0x8925
+#define SIOCSIFENCAP    0x8926
+#define SIOCGIFHWADDR   0x8927
+#define SIOCGIFSLAVE    0x8929
+#define SIOCSIFSLAVE    0x8930
+#define SIOCADDMULTI    0x8931
+#define SIOCDELMULTI    0x8932
+#define SIOCGIFINDEX    0x8933
+#define SIOGIFINDEX     SIOCGIFINDEX
+#define SIOCSIFPFLAGS   0x8934
+#define SIOCGIFPFLAGS   0x8935
+#define SIOCDIFADDR     0x8936
+#define SIOCSIFHWBROADCAST 0x8937
+#define SIOCGIFCOUNT    0x8938
+
+#define SIOCGIFBR       0x8940
+#define SIOCSIFBR       0x8941
+
+#define SIOCGIFTXQLEN   0x8942
+#define SIOCSIFTXQLEN   0x8943
+
+#define SIOCDARP        0x8953
+#define SIOCGARP        0x8954
+#define SIOCSARP        0x8955
+
+#define SIOCDRARP       0x8960
+#define SIOCGRARP       0x8961
+#define SIOCSRARP       0x8962
+
+#define SIOCGIFMAP      0x8970
+#define SIOCSIFMAP      0x8971
+
+#define SIOCADDDLCI     0x8980
+#define SIOCDELDLCI     0x8981
+
+#define SIOCDEVPRIVATE		0x89F0
+#define SIOCPROTOPRIVATE	0x89E0
diff --git a/arch/s390x/bits/ipc.h b/arch/s390x/bits/ipc.h
new file mode 100644
index 0000000..4710c12
--- /dev/null
+++ b/arch/s390x/bits/ipc.h
@@ -0,0 +1,14 @@
+struct ipc_perm {
+	key_t __ipc_perm_key;
+	uid_t uid;
+	gid_t gid;
+	uid_t cuid;
+	gid_t cgid;
+	mode_t mode;
+	unsigned short __pad1;
+	unsigned short __ipc_perm_seq;
+	unsigned long __pad2;
+	unsigned long __pad3;
+};
+
+#define IPC_64 0x100
diff --git a/arch/s390x/bits/limits.h b/arch/s390x/bits/limits.h
new file mode 100644
index 0000000..792a30b
--- /dev/null
+++ b/arch/s390x/bits/limits.h
@@ -0,0 +1,8 @@
+#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \
+ || defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+#define PAGE_SIZE 4096
+#define LONG_BIT 64
+#endif
+
+#define LONG_MAX  0x7fffffffffffffffL
+#define LLONG_MAX  0x7fffffffffffffffLL
diff --git a/arch/s390x/bits/msg.h b/arch/s390x/bits/msg.h
new file mode 100644
index 0000000..2e23ca2
--- /dev/null
+++ b/arch/s390x/bits/msg.h
@@ -0,0 +1,12 @@
+struct msqid_ds {
+	struct ipc_perm msg_perm;
+	time_t msg_stime;
+	time_t msg_rtime;
+	time_t msg_ctime;
+	unsigned long msg_cbytes;
+	msgqnum_t msg_qnum;
+	msglen_t msg_qbytes;
+	pid_t msg_lspid;
+	pid_t msg_lrpid;
+	unsigned long __unused[2];
+};
diff --git a/arch/s390x/bits/posix.h b/arch/s390x/bits/posix.h
new file mode 100644
index 0000000..c37b94c
--- /dev/null
+++ b/arch/s390x/bits/posix.h
@@ -0,0 +1,2 @@
+#define _POSIX_V6_LP64_OFF64  1
+#define _POSIX_V7_LP64_OFF64  1
diff --git a/arch/s390x/bits/reg.h b/arch/s390x/bits/reg.h
new file mode 100644
index 0000000..2633f39
--- /dev/null
+++ b/arch/s390x/bits/reg.h
@@ -0,0 +1,2 @@
+#undef __WORDSIZE
+#define __WORDSIZE 64
diff --git a/arch/s390x/bits/sem.h b/arch/s390x/bits/sem.h
new file mode 100644
index 0000000..644f68a
--- /dev/null
+++ b/arch/s390x/bits/sem.h
@@ -0,0 +1,7 @@
+struct semid_ds {
+	struct ipc_perm sem_perm;
+	time_t sem_otime;
+	time_t sem_ctime;
+	unsigned short __pad[3], sem_nsems;
+	unsigned long __unused[2];
+};
diff --git a/arch/s390x/bits/setjmp.h b/arch/s390x/bits/setjmp.h
new file mode 100644
index 0000000..b2bd974
--- /dev/null
+++ b/arch/s390x/bits/setjmp.h
@@ -0,0 +1 @@
+typedef unsigned long __jmp_buf[18];
diff --git a/arch/s390x/bits/shm.h b/arch/s390x/bits/shm.h
new file mode 100644
index 0000000..6652d65
--- /dev/null
+++ b/arch/s390x/bits/shm.h
@@ -0,0 +1,25 @@
+#define SHMLBA 4096
+
+struct shmid_ds {
+	struct ipc_perm shm_perm;
+	size_t shm_segsz;
+	time_t shm_atime;
+	time_t shm_dtime;
+	time_t shm_ctime;
+	pid_t shm_cpid;
+	pid_t shm_lpid;
+	unsigned long shm_nattch;
+	unsigned long __pad1;
+	unsigned long __pad2;
+};
+
+struct shminfo {
+	unsigned long shmmax, shmmin, shmmni, shmseg, shmall, __unused[4];
+};
+
+struct shm_info {
+	int __used_ids;
+	unsigned long shm_tot, shm_rss, shm_swp;
+	unsigned long __swap_attempts, __swap_successes;
+};
+
diff --git a/arch/s390x/bits/signal.h b/arch/s390x/bits/signal.h
new file mode 100644
index 0000000..c866583
--- /dev/null
+++ b/arch/s390x/bits/signal.h
@@ -0,0 +1,106 @@
+#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \
+ || defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+
+#if defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+#define MINSIGSTKSZ 4096
+#define SIGSTKSZ    10240
+#endif
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+
+typedef unsigned long greg_t, gregset_t[27];
+
+typedef struct {
+	unsigned long mask;
+	unsigned long addr;
+} __psw_t;
+
+typedef union {
+	double d;
+	float f;
+} fpreg_t;
+
+typedef struct {
+	unsigned fpc;
+	fpreg_t fprs[16];
+} fpregset_t;
+
+typedef struct
+{
+	__psw_t psw;
+	unsigned long gregs[16];
+	unsigned aregs[16];
+	fpregset_t fpregs;
+} mcontext_t;
+
+#else
+
+typedef struct {
+	unsigned long __regs1[18];
+	unsigned __regs2[18];
+	double __regs3[16];
+} mcontext_t;
+
+#endif
+
+struct sigaltstack {
+	void *ss_sp;
+	int ss_flags;
+	size_t ss_size;
+};
+
+typedef struct __ucontext {
+	unsigned long uc_flags;
+	struct __ucontext *uc_link;
+	stack_t uc_stack;
+	mcontext_t uc_mcontext;
+	sigset_t uc_sigmask;
+} ucontext_t;
+
+#define SA_NOCLDSTOP  1U
+#define SA_NOCLDWAIT  2U
+#define SA_SIGINFO    4U
+#define SA_ONSTACK    0x08000000U
+#define SA_RESTART    0x10000000U
+#define SA_NODEFER    0x40000000U
+#define SA_RESETHAND  0x80000000U
+#define SA_RESTORER   0x04000000U
+
+#endif
+
+#define SIGHUP    1
+#define SIGINT    2
+#define SIGQUIT   3
+#define SIGILL    4
+#define SIGTRAP   5
+#define SIGABRT   6
+#define SIGIOT    SIGABRT
+#define SIGBUS    7
+#define SIGFPE    8
+#define SIGKILL   9
+#define SIGUSR1   10
+#define SIGSEGV   11
+#define SIGUSR2   12
+#define SIGPIPE   13
+#define SIGALRM   14
+#define SIGTERM   15
+#define SIGSTKFLT 16
+#define SIGCHLD   17
+#define SIGCONT   18
+#define SIGSTOP   19
+#define SIGTSTP   20
+#define SIGTTIN   21
+#define SIGTTOU   22
+#define SIGURG    23
+#define SIGXCPU   24
+#define SIGXFSZ   25
+#define SIGVTALRM 26
+#define SIGPROF   27
+#define SIGWINCH  28
+#define SIGIO     29
+#define SIGPOLL   SIGIO
+#define SIGPWR    30
+#define SIGSYS    31
+#define SIGUNUSED SIGSYS
+
+#define _NSIG 65
diff --git a/arch/s390x/bits/socket.h b/arch/s390x/bits/socket.h
new file mode 100644
index 0000000..2b81bfe
--- /dev/null
+++ b/arch/s390x/bits/socket.h
@@ -0,0 +1,44 @@
+struct msghdr {
+	void *msg_name;
+	socklen_t msg_namelen;
+	struct iovec *msg_iov;
+	int __pad1, msg_iovlen;
+	void *msg_control;
+	int __pad2;
+	socklen_t msg_controllen;
+	int msg_flags;
+};
+
+struct cmsghdr {
+	int __pad1;
+	socklen_t cmsg_len;
+	int cmsg_level;
+	int cmsg_type;
+};
+
+#define SO_DEBUG        1
+#define SO_REUSEADDR    2
+#define SO_TYPE         3
+#define SO_ERROR        4
+#define SO_DONTROUTE    5
+#define SO_BROADCAST    6
+#define SO_SNDBUF       7
+#define SO_RCVBUF       8
+#define SO_KEEPALIVE    9
+#define SO_OOBINLINE    10
+#define SO_NO_CHECK     11
+#define SO_PRIORITY     12
+#define SO_LINGER       13
+#define SO_BSDCOMPAT    14
+#define SO_REUSEPORT    15
+#define SO_PASSCRED     16
+#define SO_PEERCRED     17
+#define SO_RCVLOWAT     18
+#define SO_SNDLOWAT     19
+#define SO_RCVTIMEO     20
+#define SO_SNDTIMEO     21
+#define SO_ACCEPTCONN   30
+#define SO_SNDBUFFORCE  32
+#define SO_RCVBUFFORCE  33
+#define SO_PROTOCOL     38
+#define SO_DOMAIN       39
diff --git a/arch/s390x/bits/stat.h b/arch/s390x/bits/stat.h
new file mode 100644
index 0000000..2db4ad0
--- /dev/null
+++ b/arch/s390x/bits/stat.h
@@ -0,0 +1,16 @@
+struct stat {
+	dev_t st_dev;
+	ino_t st_ino;
+	nlink_t st_nlink;
+	mode_t st_mode;
+	uid_t st_uid;
+	gid_t st_gid;
+	dev_t st_rdev;
+	off_t st_size;
+	struct timespec st_atim;
+	struct timespec st_mtim;
+	struct timespec st_ctim;
+	blksize_t st_blksize;
+	blkcnt_t st_blocks;
+	unsigned long __unused[3];
+};
diff --git a/arch/s390x/bits/statfs.h b/arch/s390x/bits/statfs.h
new file mode 100644
index 0000000..6617358
--- /dev/null
+++ b/arch/s390x/bits/statfs.h
@@ -0,0 +1,7 @@
+struct statfs {
+	unsigned f_type, f_bsize;
+	fsblkcnt_t f_blocks, f_bfree, f_bavail;
+	fsfilcnt_t f_files, f_ffree;
+	fsid_t f_fsid;
+	unsigned f_namelen, f_frsize, f_flags, f_spare[4];
+};
diff --git a/arch/s390x/bits/stdint.h b/arch/s390x/bits/stdint.h
new file mode 100644
index 0000000..1bb147f
--- /dev/null
+++ b/arch/s390x/bits/stdint.h
@@ -0,0 +1,20 @@
+typedef int32_t int_fast16_t;
+typedef int32_t int_fast32_t;
+typedef uint32_t uint_fast16_t;
+typedef uint32_t uint_fast32_t;
+
+#define INT_FAST16_MIN  INT32_MIN
+#define INT_FAST32_MIN  INT32_MIN
+
+#define INT_FAST16_MAX  INT32_MAX
+#define INT_FAST32_MAX  INT32_MAX
+
+#define UINT_FAST16_MAX UINT32_MAX
+#define UINT_FAST32_MAX UINT32_MAX
+
+#define INTPTR_MIN      INT64_MIN
+#define INTPTR_MAX      INT64_MAX
+#define UINTPTR_MAX     UINT64_MAX
+#define PTRDIFF_MIN     INT64_MIN
+#define PTRDIFF_MAX     INT64_MAX
+#define SIZE_MAX        UINT64_MAX
diff --git a/arch/s390x/bits/syscall.h.in b/arch/s390x/bits/syscall.h.in
new file mode 100644
index 0000000..1b8fdf0
--- /dev/null
+++ b/arch/s390x/bits/syscall.h.in
@@ -0,0 +1,323 @@
+#define __NR_exit                         1
+#define __NR_fork                         2
+#define __NR_read                         3
+#define __NR_write                        4
+#define __NR_open                         5
+#define __NR_close                        6
+#define __NR_restart_syscall              7
+#define __NR_creat                        8
+#define __NR_link                         9
+#define __NR_unlink                      10
+#define __NR_execve                      11
+#define __NR_chdir                       12
+#define __NR_mknod                       14
+#define __NR_chmod                       15
+#define __NR_lseek                       19
+#define __NR_getpid                      20
+#define __NR_mount                       21
+#define __NR_umount                      22
+#define __NR_ptrace                      26
+#define __NR_alarm                       27
+#define __NR_pause                       29
+#define __NR_utime                       30
+#define __NR_access                      33
+#define __NR_nice                        34
+#define __NR_sync                        36
+#define __NR_kill                        37
+#define __NR_rename                      38
+#define __NR_mkdir                       39
+#define __NR_rmdir                       40
+#define __NR_dup                         41
+#define __NR_pipe                        42
+#define __NR_times                       43
+#define __NR_brk                         45
+#define __NR_signal                      48
+#define __NR_acct                        51
+#define __NR_umount2                     52
+#define __NR_ioctl                       54
+#define __NR_fcntl                       55
+#define __NR_setpgid                     57
+#define __NR_umask                       60
+#define __NR_chroot                      61
+#define __NR_ustat                       62
+#define __NR_dup2                        63
+#define __NR_getppid                     64
+#define __NR_getpgrp                     65
+#define __NR_setsid                      66
+#define __NR_sigaction                   67
+#define __NR_sigsuspend                  72
+#define __NR_sigpending                  73
+#define __NR_sethostname                 74
+#define __NR_setrlimit                   75
+#define __NR_getrusage                   77
+#define __NR_gettimeofday                78
+#define __NR_settimeofday                79
+#define __NR_symlink                     83
+#define __NR_readlink                    85
+#define __NR_uselib                      86
+#define __NR_swapon                      87
+#define __NR_reboot                      88
+#define __NR_readdir                     89
+#define __NR_mmap                        90
+#define __NR_munmap                      91
+#define __NR_truncate                    92
+#define __NR_ftruncate                   93
+#define __NR_fchmod                      94
+#define __NR_getpriority                 96
+#define __NR_setpriority                 97
+#define __NR_statfs                      99
+#define __NR_fstatfs                    100
+#define __NR_socketcall                 102
+#define __NR_syslog                     103
+#define __NR_setitimer                  104
+#define __NR_getitimer                  105
+#define __NR_stat                       106
+#define __NR_lstat                      107
+#define __NR_fstat                      108
+#define __NR_lookup_dcookie             110
+#define __NR_vhangup                    111
+#define __NR_idle                       112
+#define __NR_wait4                      114
+#define __NR_swapoff                    115
+#define __NR_sysinfo                    116
+#define __NR_ipc                        117
+#define __NR_fsync                      118
+#define __NR_sigreturn                  119
+#define __NR_clone                      120
+#define __NR_setdomainname              121
+#define __NR_uname                      122
+#define __NR_adjtimex                   124
+#define __NR_mprotect                   125
+#define __NR_sigprocmask                126
+#define __NR_create_module              127
+#define __NR_init_module                128
+#define __NR_delete_module              129
+#define __NR_get_kernel_syms            130
+#define __NR_quotactl                   131
+#define __NR_getpgid                    132
+#define __NR_fchdir                     133
+#define __NR_bdflush                    134
+#define __NR_sysfs                      135
+#define __NR_personality                136
+#define __NR_afs_syscall                137
+#define __NR_getdents                   141
+#define __NR_select                     142
+#define __NR_flock                      143
+#define __NR_msync                      144
+#define __NR_readv                      145
+#define __NR_writev                     146
+#define __NR_getsid                     147
+#define __NR_fdatasync                  148
+#define __NR__sysctl                    149
+#define __NR_mlock                      150
+#define __NR_munlock                    151
+#define __NR_mlockall                   152
+#define __NR_munlockall                 153
+#define __NR_sched_setparam             154
+#define __NR_sched_getparam             155
+#define __NR_sched_setscheduler         156
+#define __NR_sched_getscheduler         157
+#define __NR_sched_yield                158
+#define __NR_sched_get_priority_max     159
+#define __NR_sched_get_priority_min     160
+#define __NR_sched_rr_get_interval      161
+#define __NR_nanosleep                  162
+#define __NR_mremap                     163
+#define __NR_query_module               167
+#define __NR_poll                       168
+#define __NR_nfsservctl                 169
+#define __NR_prctl                      172
+#define __NR_rt_sigreturn               173
+#define __NR_rt_sigaction               174
+#define __NR_rt_sigprocmask             175
+#define __NR_rt_sigpending              176
+#define __NR_rt_sigtimedwait            177
+#define __NR_rt_sigqueueinfo            178
+#define __NR_rt_sigsuspend              179
+#define __NR_pread64                    180
+#define __NR_pwrite64                   181
+#define __NR_getcwd                     183
+#define __NR_capget                     184
+#define __NR_capset                     185
+#define __NR_sigaltstack                186
+#define __NR_sendfile                   187
+#define __NR_getpmsg                    188
+#define __NR_putpmsg                    189
+#define __NR_vfork                      190
+#define __NR_getrlimit                  191
+#define __NR_lchown                     198
+#define __NR_getuid                     199
+#define __NR_getgid                     200
+#define __NR_geteuid                    201
+#define __NR_getegid                    202
+#define __NR_setreuid                   203
+#define __NR_setregid                   204
+#define __NR_getgroups                  205
+#define __NR_setgroups                  206
+#define __NR_fchown                     207
+#define __NR_setresuid                  208
+#define __NR_getresuid                  209
+#define __NR_setresgid                  210
+#define __NR_getresgid                  211
+#define __NR_chown                      212
+#define __NR_setuid                     213
+#define __NR_setgid                     214
+#define __NR_setfsuid                   215
+#define __NR_setfsgid                   216
+#define __NR_pivot_root                 217
+#define __NR_mincore                    218
+#define __NR_madvise                    219
+#define __NR_getdents64                 220
+#define __NR_readahead                  222
+#define __NR_setxattr                   224
+#define __NR_lsetxattr                  225
+#define __NR_fsetxattr                  226
+#define __NR_getxattr                   227
+#define __NR_lgetxattr                  228
+#define __NR_fgetxattr                  229
+#define __NR_listxattr                  230
+#define __NR_llistxattr                 231
+#define __NR_flistxattr                 232
+#define __NR_removexattr                233
+#define __NR_lremovexattr               234
+#define __NR_fremovexattr               235
+#define __NR_gettid                     236
+#define __NR_tkill                      237
+#define __NR_futex                      238
+#define __NR_sched_setaffinity          239
+#define __NR_sched_getaffinity          240
+#define __NR_tgkill                     241
+#define __NR_io_setup                   243
+#define __NR_io_destroy                 244
+#define __NR_io_getevents               245
+#define __NR_io_submit                  246
+#define __NR_io_cancel                  247
+#define __NR_exit_group                 248
+#define __NR_epoll_create               249
+#define __NR_epoll_ctl                  250
+#define __NR_epoll_wait                 251
+#define __NR_set_tid_address            252
+#define __NR_fadvise64                  253
+#define __NR_timer_create               254
+#define __NR_timer_settime              255
+#define __NR_timer_gettime              256
+#define __NR_timer_getoverrun           257
+#define __NR_timer_delete               258
+#define __NR_clock_settime              259
+#define __NR_clock_gettime              260
+#define __NR_clock_getres               261
+#define __NR_clock_nanosleep            262
+#define __NR_statfs64                   265
+#define __NR_fstatfs64                  266
+#define __NR_remap_file_pages           267
+#define __NR_mbind                      268
+#define __NR_get_mempolicy              269
+#define __NR_set_mempolicy              270
+#define __NR_mq_open                    271
+#define __NR_mq_unlink                  272
+#define __NR_mq_timedsend               273
+#define __NR_mq_timedreceive            274
+#define __NR_mq_notify                  275
+#define __NR_mq_getsetattr              276
+#define __NR_kexec_load                 277
+#define __NR_add_key                    278
+#define __NR_request_key                279
+#define __NR_keyctl                     280
+#define __NR_waitid                     281
+#define __NR_ioprio_set                 282
+#define __NR_ioprio_get                 283
+#define __NR_inotify_init               284
+#define __NR_inotify_add_watch          285
+#define __NR_inotify_rm_watch           286
+#define __NR_migrate_pages              287
+#define __NR_openat                     288
+#define __NR_mkdirat                    289
+#define __NR_mknodat                    290
+#define __NR_fchownat                   291
+#define __NR_futimesat                  292
+#define __NR_newfstatat                 293
+#define __NR_unlinkat                   294
+#define __NR_renameat                   295
+#define __NR_linkat                     296
+#define __NR_symlinkat                  297
+#define __NR_readlinkat                 298
+#define __NR_fchmodat                   299
+#define __NR_faccessat                  300
+#define __NR_pselect6                   301
+#define __NR_ppoll                      302
+#define __NR_unshare                    303
+#define __NR_set_robust_list            304
+#define __NR_get_robust_list            305
+#define __NR_splice                     306
+#define __NR_sync_file_range            307
+#define __NR_tee                        308
+#define __NR_vmsplice                   309
+#define __NR_move_pages                 310
+#define __NR_getcpu                     311
+#define __NR_epoll_pwait                312
+#define __NR_utimes                     313
+#define __NR_fallocate                  314
+#define __NR_utimensat                  315
+#define __NR_signalfd                   316
+#define __NR_timerfd                    317
+#define __NR_eventfd                    318
+#define __NR_timerfd_create             319
+#define __NR_timerfd_settime            320
+#define __NR_timerfd_gettime            321
+#define __NR_signalfd4                  322
+#define __NR_eventfd2                   323
+#define __NR_inotify_init1              324
+#define __NR_pipe2                      325
+#define __NR_dup3                       326
+#define __NR_epoll_create1              327
+#define __NR_preadv                     328
+#define __NR_pwritev                    329
+#define __NR_rt_tgsigqueueinfo          330
+#define __NR_perf_event_open            331
+#define __NR_fanotify_init              332
+#define __NR_fanotify_mark              333
+#define __NR_prlimit64                  334
+#define __NR_name_to_handle_at          335
+#define __NR_open_by_handle_at          336
+#define __NR_clock_adjtime              337
+#define __NR_syncfs                     338
+#define __NR_setns                      339
+#define __NR_process_vm_readv           340
+#define __NR_process_vm_writev          341
+#define __NR_s390_runtime_instr         342
+#define __NR_kcmp                       343
+#define __NR_finit_module               344
+#define __NR_sched_setattr              345
+#define __NR_sched_getattr              346
+#define __NR_renameat2                  347
+#define __NR_seccomp                    348
+#define __NR_getrandom                  349
+#define __NR_memfd_create               350
+#define __NR_bpf                        351
+#define __NR_s390_pci_mmio_write        352
+#define __NR_s390_pci_mmio_read         353
+#define __NR_execveat                   354
+#define __NR_userfaultfd                355
+#define __NR_membarrier                 356
+#define __NR_recvmmsg                   357
+#define __NR_sendmmsg                   358
+#define __NR_socket                     359
+#define __NR_socketpair                 360
+#define __NR_bind                       361
+#define __NR_connect                    362
+#define __NR_listen                     363
+#define __NR_accept4                    364
+#define __NR_getsockopt                 365
+#define __NR_setsockopt                 366
+#define __NR_getsockname                367
+#define __NR_getpeername                368
+#define __NR_sendto                     369
+#define __NR_sendmsg                    370
+#define __NR_recvfrom                   371
+#define __NR_recvmsg                    372
+#define __NR_shutdown                   373
+#define __NR_mlock2                     374
+#define __NR_copy_file_range            375
+#define __NR_preadv2                    376
+#define __NR_pwritev2                   377
+
diff --git a/arch/s390x/bits/user.h b/arch/s390x/bits/user.h
new file mode 100644
index 0000000..d2065b5
--- /dev/null
+++ b/arch/s390x/bits/user.h
@@ -0,0 +1,62 @@
+#undef __WORDSIZE
+#define __WORDSIZE 64
+
+typedef union {
+	double d;
+	float f;
+} elf_fpreg_t;
+
+typedef struct {
+	unsigned fpc;
+	fpreg_t fprs[16];
+} elf_fpregset_t;
+
+#define ELF_NGREG 27
+typedef unsigned long elf_greg_t, elf_gregset_t[ELG_NGREG];
+
+struct _user_psw_struct {
+	unsigned long mask, addr;
+};
+
+struct _user_fpregs_struct {
+	unsigned fpc;
+	double fprs[16];
+};
+
+struct _user_regs_struct {
+	struct _user_psw_struct psw;
+	unsigned long gprs[16];
+	unsigned acrs[16];
+	unsigned long orig_gpr2;
+	struct _user_fpregs_struct fp_regs;
+	struct _user_per_struct per_info;
+	unsigned long ieee_instruction_pointer;
+};
+
+struct _user_per_struct {
+	unsigned long control_regs[3];
+	unsigned single_step       : 1;
+	unsigned instruction_fetch : 1;
+	unsigned                   : 30;
+	unsigned long starting_addr, ending_addr;
+	unsigned short perc_atmid;
+	unsigned long address;
+	unsigned char access_id;
+} per_struct;
+
+struct user {
+	struct _user_regs_struct regs;
+	unsigned long u_tsize, u_dsize, u_ssize;
+	unsigned long start_code, start_stack;
+	long signal;
+	struct _user_regs_struct *u_ar0;
+	unsigned long magic;
+	char u_comm[32];
+};
+
+#define PAGE_MASK            (~(PAGE_SIZE-1))
+#define NBPG                 PAGE_SIZE
+#define UPAGES               1
+#define HOST_TEXT_START_ADDR (u.start_code)
+#define HOST_STACK_END_ADDR  (u.start_stack + u.u_ssize * NBPG)
+
diff --git a/arch/s390x/crt_arch.h b/arch/s390x/crt_arch.h
new file mode 100644
index 0000000..92091a1
--- /dev/null
+++ b/arch/s390x/crt_arch.h
@@ -0,0 +1,17 @@
+__asm__(
+".text\n"
+".global " START "\n"
+".type   " START ", %function\n"
+START ":\n"
+"	lgr  %r2, %r15\n"
+"	larl %r3, 1f\n"
+"	agf  %r3, 0(%r3)\n"
+"	aghi %r15, -160\n"
+"	lghi %r0, 0\n"
+"	stg  %r0, 0(%r15)\n"
+"	jg " START "_c\n"
+"	.align 8\n"
+".weak   _DYNAMIC\n"
+".hidden _DYNAMIC\n"
+"1:	.long _DYNAMIC-.\n"
+);
diff --git a/arch/s390x/pthread_arch.h b/arch/s390x/pthread_arch.h
new file mode 100644
index 0000000..bd90016
--- /dev/null
+++ b/arch/s390x/pthread_arch.h
@@ -0,0 +1,14 @@
+static inline struct pthread *__pthread_self()
+{
+	struct pthread *self;
+	__asm__ __volatile__ (
+		"ear  %0, %%a0\n"
+		"sllg %0, %0, 32\n"
+		"ear  %0, %%a1\n"
+		: "=r"(self));
+	return self;
+}
+
+#define TP_ADJ(p) (p)
+
+#define MC_PC psw.addr
diff --git a/arch/s390x/reloc.h b/arch/s390x/reloc.h
new file mode 100644
index 0000000..b1e4854
--- /dev/null
+++ b/arch/s390x/reloc.h
@@ -0,0 +1,17 @@
+#include <endian.h>
+
+#define LDSO_ARCH "s390x"
+
+#define REL_SYMBOLIC    R_390_64
+#define REL_GOT         R_390_GLOB_DAT
+#define REL_PLT         R_390_JMP_SLOT
+#define REL_RELATIVE    R_390_RELATIVE
+#define REL_COPY        R_390_COPY
+#define REL_DTPMOD      R_390_TLS_DTPMOD
+#define REL_DTPOFF      R_390_TLS_DTPOFF
+#define REL_TPOFF       R_390_TLS_TPOFF
+
+#define CRTJMP(pc,sp) __asm__ __volatile__( \
+	"lgr %%r15,%1; br %0" : : "r"(pc), "r"(sp) : "memory" )
+
+#define hashentry_t uint64_t
diff --git a/arch/s390x/syscall_arch.h b/arch/s390x/syscall_arch.h
new file mode 100644
index 0000000..afb9985
--- /dev/null
+++ b/arch/s390x/syscall_arch.h
@@ -0,0 +1,76 @@
+#define __SYSCALL_LL_E(x) (x)
+#define __SYSCALL_LL_O(x) (x)
+
+#define __asm_syscall(ret, ...) do { \
+	__asm__ __volatile__ ("svc 0\n" \
+	: ret : __VA_ARGS__ : "memory"); \
+	return r2; \
+	} while (0)
+
+static inline long __syscall0(long n)
+{
+	register long r1 __asm__("r1") = n;
+	register long r2 __asm__("r2");
+	__asm_syscall("=r"(r2), "r"(r1));
+}
+
+static inline long __syscall1(long n, long a)
+{
+	register long r1 __asm__("r1") = n;
+	register long r2 __asm__("r2") = a;
+	__asm_syscall("+r"(r2), "r"(r1));
+}
+
+static inline long __syscall2(long n, long a, long b)
+{
+	register long r1 __asm__("r1") = n;
+	register long r2 __asm__("r2") = a;
+	register long r3 __asm__("r3") = b;
+	__asm_syscall("+r"(r2), "r"(r1), "r"(r3));
+}
+
+static inline long __syscall3(long n, long a, long b, long c)
+{
+	register long r1 __asm__("r1") = n;
+	register long r2 __asm__("r2") = a;
+	register long r3 __asm__("r3") = b;
+	register long r4 __asm__("r4") = c;
+	__asm_syscall("+r"(r2), "r"(r1), "r"(r3), "r"(r4));
+}
+
+static inline long __syscall4(long n, long a, long b, long c, long d)
+{
+	register long r1 __asm__("r1") = n;
+	register long r2 __asm__("r2") = a;
+	register long r3 __asm__("r3") = b;
+	register long r4 __asm__("r4") = c;
+	register long r5 __asm__("r5") = d;
+	__asm_syscall("+r"(r2), "r"(r1), "r"(r3), "r"(r4), "r"(r5));
+}
+
+static inline long __syscall5(long n, long a, long b, long c, long d, long e)
+{
+	register long r1 __asm__("r1") = n;
+	register long r2 __asm__("r2") = a;
+	register long r3 __asm__("r3") = b;
+	register long r4 __asm__("r4") = c;
+	register long r5 __asm__("r5") = d;
+	register long r6 __asm__("r6") = e;
+	__asm_syscall("+r"(r2), "r"(r1), "r"(r3), "r"(r4), "r"(r5), "r"(r6));
+}
+
+static inline long __syscall6(long n, long a, long b, long c, long d, long e, long f)
+{
+	if (n == SYS_mmap) return __syscall1(n, (long)(long[]){a,b,c,d,e,f});
+
+	register long r1 __asm__("r1") = n;
+	register long r2 __asm__("r2") = a;
+	register long r3 __asm__("r3") = b;
+	register long r4 __asm__("r4") = c;
+	register long r5 __asm__("r5") = d;
+	register long r6 __asm__("r6") = e;
+	register long r7 __asm__("r7") = f;
+	__asm_syscall("+r"(r2), "r"(r1), "r"(r3), "r"(r4), "r"(r5), "r"(r6), "r"(r7));
+}
+
+#define SYSCALL_USE_SOCKETCALL
diff --git a/configure b/configure
index af8b45f..56ddafb 100755
--- a/configure
+++ b/configure
@@ -325,6 +325,7 @@ or1k*) ARCH=or1k ;;
 powerpc64*) ARCH=powerpc64 ;;
 powerpc*) ARCH=powerpc ;;
 sh[1-9bel-]*|sh|superh*) ARCH=sh ;;
+s390x*) ARCH=s390x ;;
 unknown) fail "$0: unable to detect target arch; try $0 --target=..." ;;
 *) fail "$0: unknown or unsupported target \"$target\"" ;;
 esac
diff --git a/crt/s390x/crti.s b/crt/s390x/crti.s
new file mode 100644
index 0000000..f453205
--- /dev/null
+++ b/crt/s390x/crti.s
@@ -0,0 +1,17 @@
+.section .init
+.align 2
+.global _init
+_init:
+	stmg %r14, %r15, 112(%r15)
+	lgr  %r0,  %r15
+	aghi %r15, -160
+	stg  %r0,  0(%r15)
+
+.section .fini
+.align 2
+.global _fini
+_fini:
+	stmg %r14, %r15, 112(%r15)
+	lgr  %r0,  %r15
+	aghi %r15, -160
+	stg  %r0,  0(%r15)
diff --git a/crt/s390x/crtn.s b/crt/s390x/crtn.s
new file mode 100644
index 0000000..06066dc
--- /dev/null
+++ b/crt/s390x/crtn.s
@@ -0,0 +1,9 @@
+.section .init
+.align 2
+	lmg  %r14, %r15, 272(%r15)
+	br   %r14
+
+.section .fini
+.align 2
+	lmg  %r14, %r15, 272(%r15)
+	br   %r14
diff --git a/src/fenv/s390x/fenv.c b/src/fenv/s390x/fenv.c
new file mode 100644
index 0000000..9a3488d
--- /dev/null
+++ b/src/fenv/s390x/fenv.c
@@ -0,0 +1,55 @@
+#include <fenv.h>
+
+static inline unsigned get_fpc(void)
+{
+	unsigned fpc;
+	__asm__ __volatile__("efpc %0" : "=r"(fpc));
+	return fpc;
+}
+
+static inline void set_fpc(unsigned fpc)
+{
+	__asm__ __volatile__("sfpc %0" :: "r"(fpc));
+}
+
+int feclearexcept(int mask)
+{
+	mask &= FE_ALL_EXCEPT;
+	set_fpc(get_fpc() & ~mask);
+	return 0;
+}
+
+int feraiseexcept(int mask)
+{
+	mask &= FE_ALL_EXCEPT;
+	set_fpc(get_fpc() | mask);
+	return 0;
+}
+
+int fetestexcept(int mask)
+{
+	return get_fpc() & mask & FE_ALL_EXCEPT;
+}
+
+int fegetround(void)
+{
+	return get_fpc() & 3;
+}
+
+int __fesetround(int r)
+{
+	set_fpc(get_fpc() & ~3L | r);
+	return 0;
+}
+
+int fegetenv(fenv_t *envp)
+{
+	*envp = get_fpc();
+	return 0;
+}
+
+int fesetenv(const fenv_t *envp)
+{
+	set_fpc(envp != FE_DFL_ENV ? *envp : 0);
+	return 0;
+}
diff --git a/src/internal/s390x/syscall.s b/src/internal/s390x/syscall.s
new file mode 100644
index 0000000..2322bc3
--- /dev/null
+++ b/src/internal/s390x/syscall.s
@@ -0,0 +1,15 @@
+.global __syscall
+.hidden __syscall
+.type   __syscall, %function
+__syscall:
+	stg %r7, 56(%r15)
+	lgr %r1, %r2
+	lgr %r2, %r3
+	lgr %r3, %r4
+	lgr %r4, %r5
+	lgr %r5, %r6
+	lg  %r6, 160(%r15)
+	lg  %r7, 168(%r15)
+	svc 0
+	lg  %r7, 56(%r15)
+	br  %r14
diff --git a/src/process/s390x/vfork.s b/src/process/s390x/vfork.s
new file mode 100644
index 0000000..05956e8
--- /dev/null
+++ b/src/process/s390x/vfork.s
@@ -0,0 +1,8 @@
+	.global __vfork
+	.weak vfork
+	.type __vfork,%function
+	.type vfork,%function
+__vfork:
+vfork:
+	svc 190
+	jg  __syscall_ret
diff --git a/src/setjmp/s390x/longjmp.s b/src/setjmp/s390x/longjmp.s
new file mode 100644
index 0000000..b2310f8
--- /dev/null
+++ b/src/setjmp/s390x/longjmp.s
@@ -0,0 +1,23 @@
+	.global _longjmp
+	.global longjmp
+	.type   _longjmp,@function
+	.type   longjmp,@function
+_longjmp:
+longjmp:
+
+1:
+	lmg %r6, %r15, 0(%r2)
+
+	ld  %f8, 10*8(%r2)
+	ld  %f9, 11*8(%r2)
+	ld %f10, 12*8(%r2)
+	ld %f11, 13*8(%r2)
+	ld %f12, 14*8(%r2)
+	ld %f13, 15*8(%r2)
+	ld %f14, 16*8(%r2)
+	ld %f15, 17*8(%r2)
+
+	ltgr %r2, %r3
+	bnzr %r14
+	lhi  %r2, 1
+	br   %r14
diff --git a/src/setjmp/s390x/setjmp.s b/src/setjmp/s390x/setjmp.s
new file mode 100644
index 0000000..afae1b6
--- /dev/null
+++ b/src/setjmp/s390x/setjmp.s
@@ -0,0 +1,25 @@
+	.global ___setjmp
+	.hidden ___setjmp
+	.global __setjmp
+	.global _setjmp
+	.global setjmp
+	.type   __setjmp,@function
+	.type   _setjmp,@function
+	.type   setjmp,@function
+___setjmp:
+__setjmp:
+_setjmp:
+setjmp:
+	stmg %r6, %r15, 0(%r2)
+
+	std  %f8,  10*8(%r2)
+	std  %f9,  11*8(%r2)
+	std  %f10, 12*8(%r2)
+	std  %f11, 13*8(%r2)
+	std  %f12, 14*8(%r2)
+	std  %f13, 15*8(%r2)
+	std  %f14, 16*8(%r2)
+	std  %f15, 17*8(%r2)
+
+	lghi %r2, 0
+	br   %r14
diff --git a/src/signal/s390x/restore.s b/src/signal/s390x/restore.s
new file mode 100644
index 0000000..79beb68
--- /dev/null
+++ b/src/signal/s390x/restore.s
@@ -0,0 +1,9 @@
+	.global __restore
+	.type __restore,%function
+__restore:
+	svc 119 #__NR_sigreturn
+
+	.global __restore_rt
+	.type __restore_rt,%function
+__restore_rt:
+	svc 173 # __NR_rt_sigreturn
diff --git a/src/signal/s390x/sigsetjmp.s b/src/signal/s390x/sigsetjmp.s
new file mode 100644
index 0000000..72dfc25
--- /dev/null
+++ b/src/signal/s390x/sigsetjmp.s
@@ -0,0 +1,23 @@
+	.global sigsetjmp
+	.global __sigsetjmp
+	.type sigsetjmp,%function
+	.type __sigsetjmp,%function
+	.hidden ___setjmp
+sigsetjmp:
+__sigsetjmp:
+	ltgr  %r3, %r3
+	bz    ___setjmp
+
+	stg   %r14, 18*8(%r2)
+	stg   %r6,  20*8(%r2)
+	lgr   %r6,  %r2
+
+	brasl %r14, ___setjmp
+
+	lgr   %r3,  %r2
+	lgr   %r2,  %r6
+	lg    %r14, 18*8(%r2)
+	lg    %r6,  20*8(%r2)
+
+.hidden __sigsetjmp_tail
+	jg __sigsetjmp_tail
diff --git a/src/thread/s390x/__set_thread_area.s b/src/thread/s390x/__set_thread_area.s
new file mode 100644
index 0000000..fd41291
--- /dev/null
+++ b/src/thread/s390x/__set_thread_area.s
@@ -0,0 +1,9 @@
+.text
+.global __set_thread_area
+.type   __set_thread_area, %function
+__set_thread_area:
+	sar  %a1, %r2
+	srlg %r2, %r2, 32
+	sar  %a0, %r2
+	lghi %r2, 0
+	br   %r14
diff --git a/src/thread/s390x/__tls_get_offset.s b/src/thread/s390x/__tls_get_offset.s
new file mode 100644
index 0000000..8ee92de
--- /dev/null
+++ b/src/thread/s390x/__tls_get_offset.s
@@ -0,0 +1,17 @@
+	.global __tls_get_offset
+	.type __tls_get_offset,%function
+__tls_get_offset:
+	stmg  %r14, %r15, 112(%r15)
+	aghi  %r15, -160
+
+	la    %r2, 0(%r2, %r12)
+	brasl %r14, __tls_get_addr
+
+	ear   %r1, %a0
+	sllg  %r1, %r1, 32
+	ear   %r1, %a1
+
+	sgr   %r2, %r1
+
+	lmg   %r14, %r15, 272(%r15)
+	br    %r14
diff --git a/src/thread/s390x/__unmapself.s b/src/thread/s390x/__unmapself.s
new file mode 100644
index 0000000..48b312c
--- /dev/null
+++ b/src/thread/s390x/__unmapself.s
@@ -0,0 +1,6 @@
+.text
+.global __unmapself
+.type   __unmapself, @function
+__unmapself:
+	svc 91 # SYS_munmap
+	svc 1  # SYS_exit
diff --git a/src/thread/s390x/clone.s b/src/thread/s390x/clone.s
new file mode 100644
index 0000000..3e08c21
--- /dev/null
+++ b/src/thread/s390x/clone.s
@@ -0,0 +1,47 @@
+.text
+.global __clone
+.type __clone, %function
+__clone:
+	# int clone(
+	#    fn,      a = r2
+	#    stack,   b = r3
+	#    flags,   c = r4
+	#    arg,     d = r5
+	#    ptid,    e = r6
+	#    tls,     f = *(r15+160)
+	#    ctid)    g = *(r15+168)
+	#
+	# pseudo C code:
+	# tid = syscall(SYS_clone,b,c,e,g,f);
+	# if (!tid) syscall(SYS_exit, a(d));
+	# return tid;
+
+	# create initial stack frame for new thread
+	nill %r3, 0xfff8
+	aghi %r3, -160
+	lghi %r0, 0
+	stg  %r0, 0(%r3)
+
+	# save fn and arg to child stack
+	stg  %r2,  8(%r3)
+	stg  %r5, 16(%r3)
+
+	# shuffle args into correct registers and call SYS_clone
+	lgr  %r2, %r3
+	lgr  %r3, %r4
+	lgr  %r4, %r6
+	lg   %r5, 168(%r15)
+	lg   %r6, 160(%r15)
+	svc  120
+
+	# if error or if we're the parent, return
+	ltgr %r2, %r2
+	bnzr %r14
+
+	# we're the child. call fn(arg)
+	lg   %r1,  8(%r15)
+	lg   %r2, 16(%r15)
+	basr %r14, %r1
+
+	# call SYS_exit. exit code is already in r2 from fn return value
+	svc  1
diff --git a/src/thread/s390x/syscall_cp.s b/src/thread/s390x/syscall_cp.s
new file mode 100644
index 0000000..c1da40d
--- /dev/null
+++ b/src/thread/s390x/syscall_cp.s
@@ -0,0 +1,32 @@
+	.global __cp_begin
+	.hidden __cp_begin
+	.global __cp_end
+	.hidden __cp_end
+	.global __cp_cancel
+	.hidden __cp_cancel
+	.hidden __cancel
+	.global __syscall_cp_asm
+	.hidden __syscall_cp_asm
+	.text
+	.type   __syscall_cp_asm,%function
+__syscall_cp_asm:
+__cp_begin:
+	icm %r2, 15, 0(%r2)
+	jne __cp_cancel
+
+	stg %r7, 56(%r15)
+	lgr %r1, %r3
+	lgr %r2, %r4
+	lgr %r3, %r5
+	lgr %r4, %r6
+	lg  %r5, 160(%r15)
+	lg  %r6, 168(%r15)
+	lg  %r7, 176(%r15)
+	svc 0
+
+__cp_end:
+	lg  %r7, 56(%r15)
+	br  %r14
+
+__cp_cancel:
+	jg  __cancel
-- 
2.9.0

Powered by blists - more mailing lists

Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.