* [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).