mailing list of musl libc
 help / color / mirror / code / Atom feed
* [PATCH 1/3] treat null vdso base same as missing
@ 2016-07-26  3:52 Bobby Bingham
  2016-07-26  3:52 ` [PATCH 2/3] allow different size hash table entries Bobby Bingham
  2016-07-26  3:53 ` [PATCH 3/3] add s390x port Bobby Bingham
  0 siblings, 2 replies; 7+ messages in thread
From: Bobby Bingham @ 2016-07-26  3:52 UTC (permalink / raw)
  To: musl

On s390x, the kernel provides AT_SYSINFO_EHDR, but sets it to zero, if the
program being run does not have a program interpreter.  This causes
problems when running the dynamic linker directly.
---
 ldso/dynlink.c      | 2 +-
 src/internal/vdso.c | 1 +
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/ldso/dynlink.c b/ldso/dynlink.c
index e458f38..5a9e2ba 100644
--- a/ldso/dynlink.c
+++ b/ldso/dynlink.c
@@ -1549,7 +1549,7 @@ _Noreturn void __dls3(size_t *sp)
 	}
 
 	/* Attach to vdso, if provided by the kernel */
-	if (search_vec(auxv, &vdso_base, AT_SYSINFO_EHDR)) {
+	if (search_vec(auxv, &vdso_base, AT_SYSINFO_EHDR) && vdso_base) {
 		Ehdr *ehdr = (void *)vdso_base;
 		Phdr *phdr = vdso.phdr = (void *)(vdso_base + ehdr->e_phoff);
 		vdso.phnum = ehdr->e_phnum;
diff --git a/src/internal/vdso.c b/src/internal/vdso.c
index 6ae0212..ff392bc 100644
--- a/src/internal/vdso.c
+++ b/src/internal/vdso.c
@@ -44,6 +44,7 @@ void *__vdsosym(const char *vername, const char *name)
 	size_t i;
 	for (i=0; libc.auxv[i] != AT_SYSINFO_EHDR; i+=2)
 		if (!libc.auxv[i]) return 0;
+	if (!libc.auxv[i+1]) return 0;
 	Ehdr *eh = (void *)libc.auxv[i+1];
 	Phdr *ph = (void *)((char *)eh + eh->e_phoff);
 	size_t *dynv=0, base=-1;
-- 
2.9.0



^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH 2/3] allow different size hash table entries
  2016-07-26  3:52 [PATCH 1/3] treat null vdso base same as missing Bobby Bingham
@ 2016-07-26  3:52 ` Bobby Bingham
  2016-07-27 16:49   ` Alexander Monakov
  2016-07-26  3:53 ` [PATCH 3/3] add s390x port Bobby Bingham
  1 sibling, 1 reply; 7+ messages in thread
From: Bobby Bingham @ 2016-07-26  3:52 UTC (permalink / raw)
  To: musl

The sysv hash table for dynamic symbol lookups is supposed to always have
32 bit entries, but some architectures (alpha, s390x) botched the abi and
use 64 bit entries.  Despite this, the hash function is the same, and still
only produces 32 bit hash values.
---
 ldso/dynlink.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/ldso/dynlink.c b/ldso/dynlink.c
index 5a9e2ba..63f0e0a 100644
--- a/ldso/dynlink.c
+++ b/ldso/dynlink.c
@@ -21,6 +21,10 @@
 #include "libc.h"
 #include "dynlink.h"
 
+#ifndef hashentry_t
+#define hashentry_t uint32_t
+#endif
+
 static void error(const char *, ...);
 
 #define MAXP2(a,b) (-(-(a)&-(b)))
@@ -54,7 +58,7 @@ struct dso {
 	size_t phentsize;
 	int refcnt;
 	Sym *syms;
-	uint32_t *hashtab;
+	hashentry_t *hashtab;
 	uint32_t *ghashtab;
 	int16_t *versym;
 	char *strings;
@@ -206,7 +210,7 @@ static Sym *sysv_lookup(const char *s, uint32_t h, struct dso *dso)
 {
 	size_t i;
 	Sym *syms = dso->syms;
-	uint32_t *hashtab = dso->hashtab;
+	hashentry_t *hashtab = dso->hashtab;
 	char *strings = dso->strings;
 	for (i=hashtab[2+h%hashtab[0]]; i; i=hashtab[2+hashtab[0]+i]) {
 		if ((!dso->versym || dso->versym[i] >= 0)
-- 
2.9.0



^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH 3/3] add s390x port
  2016-07-26  3:52 [PATCH 1/3] treat null vdso base same as missing Bobby Bingham
  2016-07-26  3:52 ` [PATCH 2/3] allow different size hash table entries Bobby Bingham
@ 2016-07-26  3:53 ` Bobby Bingham
  2016-10-21 20:27   ` Rich Felker
  1 sibling, 1 reply; 7+ messages in thread
From: Bobby Bingham @ 2016-07-26  3:53 UTC (permalink / raw)
  To: musl

---
 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



^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH 2/3] allow different size hash table entries
  2016-07-26  3:52 ` [PATCH 2/3] allow different size hash table entries Bobby Bingham
@ 2016-07-27 16:49   ` Alexander Monakov
  0 siblings, 0 replies; 7+ messages in thread
From: Alexander Monakov @ 2016-07-27 16:49 UTC (permalink / raw)
  To: musl

On Mon, 25 Jul 2016, Bobby Bingham wrote:

> The sysv hash table for dynamic symbol lookups is supposed to always have
> 32 bit entries, but some architectures (alpha, s390x) botched the abi and
> use 64 bit entries.  Despite this, the hash function is the same, and still
> only produces 32 bit hash values.

Note, Glibc does not specialize its lookup code for those platforms; instead,
they use user-visible type Elf_Symndx (exposed via link.h, also on musl) to
denote the type of hash table entries; Alpha and s390 override this type
appropriately in their arch-specific headers.

This suggests that musl should also define Elf_Symndx as a 64-bit type
(otherwise it's incompatible), and then dynlink.c admits a cleaner fix (i.e.
using Elf_Symndx where appropriate, without a new #ifndef).

HTH
Alexander


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH 3/3] add s390x port
  2016-07-26  3:53 ` [PATCH 3/3] add s390x port Bobby Bingham
@ 2016-10-21 20:27   ` Rich Felker
  2016-10-22  0:15     ` Bobby Bingham
  0 siblings, 1 reply; 7+ messages in thread
From: Rich Felker @ 2016-10-21 20:27 UTC (permalink / raw)
  To: musl

Sorry for taking so long to give this the attention it deserves. I
think it looks good and is mostly ready to commit. A few
questions/comments though:

On Mon, Jul 25, 2016 at 10:53:00PM -0500, Bobby Bingham wrote:
> 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;

Reportedly this is wrong (a bug copied from glibc) and floats are
actually evaluated as float on s390. Can you check and confirm?

> 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;
> +};

__ipc_perm_seq is int on other archs, without the padding. It's not a
standard type so I don't think we're forced to have matching type, but
I wonder why this is. OTOH maybe some current archs are buggy because
of this..

> diff --git a/arch/s390x/syscall_arch.h b/arch/s390x/syscall_arch.h
> [...]
> +#define SYSCALL_USE_SOCKETCALL

Is this intentional? s390x does not (or did not always) have dedicated
syscalls for socket ops?

> 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

Can you explain this function and why a tail-call to __tls_get_addr
doesn't work? Based on the (albeit 32-bit) info in
https://www.akkadia.org/drepper/tls.pdf it seems like it could but
maybe I'm missing something. Is there a special contract about
clobbers?

Rich


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH 3/3] add s390x port
  2016-10-21 20:27   ` Rich Felker
@ 2016-10-22  0:15     ` Bobby Bingham
  2016-10-22  2:59       ` Rich Felker
  0 siblings, 1 reply; 7+ messages in thread
From: Bobby Bingham @ 2016-10-22  0:15 UTC (permalink / raw)
  To: musl

On Fri, Oct 21, 2016 at 04:27:02PM -0400, Rich Felker wrote:
> Sorry for taking so long to give this the attention it deserves. I
> think it looks good and is mostly ready to commit. A few
> questions/comments though:

Thanks for the review.

> 
> On Mon, Jul 25, 2016 at 10:53:00PM -0500, Bobby Bingham wrote:
> > 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;
> 
> Reportedly this is wrong (a bug copied from glibc) and floats are
> actually evaluated as float on s390. Can you check and confirm?

It's evaluating as double here on gcc 4.9.

printf("%f", FLT_MAX * 2.0f) outputs
680564693277057719623408366969033850880.000000 rather than inf.

> 
> > 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;
> > +};
> 
> __ipc_perm_seq is int on other archs, without the padding. It's not a
> standard type so I don't think we're forced to have matching type, but
> I wonder why this is. OTOH maybe some current archs are buggy because
> of this..
> 

Strange.  FWIW, it is unsigned short on aarch64 already as well.  And the
kernel type is int for ppc(64), so that architecture is probably fine.

> > diff --git a/arch/s390x/syscall_arch.h b/arch/s390x/syscall_arch.h
> > [...]
> > +#define SYSCALL_USE_SOCKETCALL
> 
> Is this intentional? s390x does not (or did not always) have dedicated
> syscalls for socket ops?

The dedicated syscalls were only added a year ago in kernel 4.3
(kernel commit 977108f89c989b1eeb5c8d938e1e71913391eb5f)

> 
> > 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
> 
> Can you explain this function and why a tail-call to __tls_get_addr
> doesn't work? Based on the (albeit 32-bit) info in
> https://www.akkadia.org/drepper/tls.pdf it seems like it could but
> maybe I'm missing something. Is there a special contract about
> clobbers?

A tail call doesn't work because the return values aren't the same.  From
the linked document:

> The return value of __tls_get_offset is an offset to the thread pointer.
> To get the address of the requested variable the thread pointer needs to
> be added to the return value.

This function is essentially:

	size_t __tls_get_offset(size_t offset, char *got)
	{
		return (char*)__tls_get_addr(got + offset) - (char*)__pthread_self();
	}

Except that the second parameter is passed via r12 instead of the usual r3,
which is why it's written in assembly.

--
Bobby


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH 3/3] add s390x port
  2016-10-22  0:15     ` Bobby Bingham
@ 2016-10-22  2:59       ` Rich Felker
  0 siblings, 0 replies; 7+ messages in thread
From: Rich Felker @ 2016-10-22  2:59 UTC (permalink / raw)
  To: musl

On Fri, Oct 21, 2016 at 07:15:19PM -0500, Bobby Bingham wrote:
> > On Mon, Jul 25, 2016 at 10:53:00PM -0500, Bobby Bingham wrote:
> > > 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;
> > 
> > Reportedly this is wrong (a bug copied from glibc) and floats are
> > actually evaluated as float on s390. Can you check and confirm?
> 
> It's evaluating as double here on gcc 4.9.
> 
> printf("%f", FLT_MAX * 2.0f) outputs
> 680564693277057719623408366969033850880.000000 rather than inf.

OK, the story is more complicated it seems -- gcc is emitting code to
do extra work to promote it to double to match a mistake in the glibc
ABI. Details in this thread:

https://www.mail-archive.com/gcc-patches@gcc.gnu.org/msg148879.html

Fixing it was discussed but seems to have been dropped, and the
current behavior at least seems to be internally consistent as long as
you're in standards-conforming modes.

I don't care about the arch enough personally for me to push for
fixing it for musl target, but if someone else wants to, please speak
up. Of course we could make it dynamic like i386 (which changes based
on -mfpmath=sse) later if it turns out there is a fix on the gcc side.

> > > 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;
> > > +};
> > 
> > __ipc_perm_seq is int on other archs, without the padding. It's not a
> > standard type so I don't think we're forced to have matching type, but
> > I wonder why this is. OTOH maybe some current archs are buggy because
> > of this..
> 
> Strange.  FWIW, it is unsigned short on aarch64 already as well.  And the
> kernel type is int for ppc(64), so that architecture is probably fine.

If the kernel type is short, I would think using int without the
padding field only works when the paddign is placed to match the
endianness. Of course here it does match, but I wonder whether it does
on mips, powerpc, sh, etc. This isn't something you need to follow-up
on; I'm just noting it here so there's a record of it.

> > > diff --git a/arch/s390x/syscall_arch.h b/arch/s390x/syscall_arch.h
> > > [...]
> > > +#define SYSCALL_USE_SOCKETCALL
> > 
> > Is this intentional? s390x does not (or did not always) have dedicated
> > syscalls for socket ops?
> 
> The dedicated syscalls were only added a year ago in kernel 4.3
> (kernel commit 977108f89c989b1eeb5c8d938e1e71913391eb5f)

OK, then this is fine as-is.

> > > 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
> > 
> > Can you explain this function and why a tail-call to __tls_get_addr
> > doesn't work? Based on the (albeit 32-bit) info in
> > https://www.akkadia.org/drepper/tls.pdf it seems like it could but
> > maybe I'm missing something. Is there a special contract about
> > clobbers?
> 
> A tail call doesn't work because the return values aren't the same.  From
> the linked document:
> 
> > The return value of __tls_get_offset is an offset to the thread pointer.
> > To get the address of the requested variable the thread pointer needs to
> > be added to the return value.
> 
> This function is essentially:
> 
> 	size_t __tls_get_offset(size_t offset, char *got)
> 	{
> 		return (char*)__tls_get_addr(got + offset) - (char*)__pthread_self();
> 	}
> 
> Except that the second parameter is passed via r12 instead of the usual r3,
> which is why it's written in assembly.

OK. It might make sense to write a fast-path in asm when the dtv slot
is already present (see src/thread/i386/tls.s for a similar example)
but this could be improved in a later patch. It's not blocking merge
by any means.

Rich


^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2016-10-22  2:59 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-07-26  3:52 [PATCH 1/3] treat null vdso base same as missing Bobby Bingham
2016-07-26  3:52 ` [PATCH 2/3] allow different size hash table entries Bobby Bingham
2016-07-27 16:49   ` Alexander Monakov
2016-07-26  3:53 ` [PATCH 3/3] add s390x port Bobby Bingham
2016-10-21 20:27   ` Rich Felker
2016-10-22  0:15     ` Bobby Bingham
2016-10-22  2:59       ` Rich Felker

Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/musl/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).