From 15094943050eb9a564f409323070e50b40f78816 Mon Sep 17 00:00:00 2001 From: Bobby Bingham Date: Fri, 11 Nov 2016 21:52:05 -0600 Subject: [PATCH] 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/link.h | 1 + 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 | 15 ++ 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 +++ 42 files changed, 1393 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/link.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 00000000..9b0e1df9 --- /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 00000000..1a838462 --- /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 00000000..ef074b77 --- /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 00000000..1eca6ba5 --- /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 00000000..773dad91 --- /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 00000000..90b73bee --- /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 00000000..11196e15 --- /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 00000000..4710c12b --- /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 00000000..792a30b9 --- /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/link.h b/arch/s390x/bits/link.h new file mode 100644 index 00000000..923aac57 --- /dev/null +++ b/arch/s390x/bits/link.h @@ -0,0 +1 @@ +typedef uint64_t Elf_Symndx; diff --git a/arch/s390x/bits/msg.h b/arch/s390x/bits/msg.h new file mode 100644 index 00000000..2e23ca27 --- /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 00000000..c37b94c1 --- /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 00000000..2633f39d --- /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 00000000..644f68a0 --- /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 00000000..b2bd9748 --- /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 00000000..6652d659 --- /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 00000000..c8665832 --- /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 00000000..2b81bfec --- /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 00000000..2db4ad02 --- /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 00000000..6617358a --- /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 00000000..1bb147f2 --- /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 00000000..1b8fdf0c --- /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 00000000..d2065b5e --- /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 00000000..92091a10 --- /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 00000000..bd90016d --- /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 00000000..a238dc65 --- /dev/null +++ b/arch/s390x/reloc.h @@ -0,0 +1,15 @@ +#include + +#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" ) diff --git a/arch/s390x/syscall_arch.h b/arch/s390x/syscall_arch.h new file mode 100644 index 00000000..afb99852 --- /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 707eb125..81e90f79 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 00000000..f453205b --- /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 00000000..06066dc9 --- /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 00000000..9a3488d7 --- /dev/null +++ b/src/fenv/s390x/fenv.c @@ -0,0 +1,55 @@ +#include + +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 00000000..2322bc36 --- /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 00000000..05956e81 --- /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 00000000..b2310f8a --- /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 00000000..afae1b67 --- /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 00000000..79beb68f --- /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 00000000..72dfc25d --- /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 00000000..fd412913 --- /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 00000000..8ee92de8 --- /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 00000000..48b312cd --- /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 00000000..3e08c213 --- /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 00000000..c1da40de --- /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.25.1