mailing list of musl libc
 help / color / mirror / code / Atom feed
* [RFC][PATCH] x32: initial draft of port
@ 2013-12-28  0:07 John Spencer
  0 siblings, 0 replies; only message in thread
From: John Spencer @ 2013-12-28  0:07 UTC (permalink / raw)
  To: musl

[-- Attachment #1: Type: text/plain, Size: 1101 bytes --]

I started off copying the x86_64 port, getting static build to work
and then iteratively fixing problems detected by libc-testsuite.
currently not containing any of the optimized math and string asm.
at this point all tests except math pass, and both static and dynamic
linking work.

there are a couple of intrusive changes into non-arch specific headers,
caused by mismatch of 32bit longs to "kernel" longs (64bit) used in
some structures and as syscall arguments.

especially the current changes to src/internal/syscall.h are very ugly.

discussion is open for better/cleaner ways to get the same
functionality.

something that didn't make it into this patch is that the arch triple
"x86_64-x32-..." should also be detected by the configure script,
because this is a triple that magically let's binutils and gcc build the
right thing (gcc needs an additional multilib setting to work tho,
--with-multilib-list=mx32). having the arch name itself be x32 seems
cleaner though, especially with regard to the musl-gcc patches in
Gregor's repo that already have ld-musl-x32.so.1 hardcoded as dynlinker.


[-- Attachment #2: x32.patch --]
[-- Type: text/plain, Size: 87345 bytes --]

From 5f4e54f8f40dc700e52e1a6bcb37a66f4fe4e438 Mon Sep 17 00:00:00 2001
Subject: [RFC][PATCH] x32: initial draft of port

---
 arch/x32/atomic.h                  | 127 ++++++++
 arch/x32/bits/alltypes.h.in        |  28 ++
 arch/x32/bits/endian.h             |   1 +
 arch/x32/bits/errno.h              | 134 ++++++++
 arch/x32/bits/fcntl.h              |  39 +++
 arch/x32/bits/fenv.h               |  34 ++
 arch/x32/bits/float.h              |  21 ++
 arch/x32/bits/io.h                 |  77 +++++
 arch/x32/bits/ioctl.h              | 197 ++++++++++++
 arch/x32/bits/ipc.h                |  14 +
 arch/x32/bits/limits.h             |   8 +
 arch/x32/bits/mman.h               |  62 ++++
 arch/x32/bits/msg.h                |  13 +
 arch/x32/bits/posix.h              |   2 +
 arch/x32/bits/reg.h                |  29 ++
 arch/x32/bits/setjmp.h             |   1 +
 arch/x32/bits/shm.h                |  15 +
 arch/x32/bits/signal.h             | 119 +++++++
 arch/x32/bits/socket.h             |  18 ++
 arch/x32/bits/stat.h               |  22 ++
 arch/x32/bits/statfs.h             |   7 +
 arch/x32/bits/stdarg.h             |   4 +
 arch/x32/bits/stdint.h             |  20 ++
 arch/x32/bits/syscall.h            | 634 +++++++++++++++++++++++++++++++++++++
 arch/x32/bits/termios.h            | 160 ++++++++++
 arch/x32/bits/user.h               |  44 +++
 arch/x32/crt_arch.h                |   9 +
 arch/x32/pthread_arch.h            |  10 +
 arch/x32/reloc.h                   |  46 +++
 arch/x32/syscall_arch.h            |  65 ++++
 configure                          |   1 +
 crt/x32/Scrt1.s                    |  16 +
 crt/x32/crt1.s                     |  20 ++
 crt/x32/crti.s                     |   9 +
 crt/x32/crtn.s                     |   7 +
 include/sys/msg.h                  |   9 +
 include/sys/sem.h                  |  22 +-
 include/sys/shm.h                  |  16 +-
 src/internal/syscall.h             |  48 ++-
 src/internal/x32/syscall.s         |  12 +
 src/ldso/x32/dlsym.s               |   6 +
 src/ldso/x32/start.s               |  24 ++
 src/process/x32/vfork.s            |  12 +
 src/setjmp/x32/longjmp.s           |  22 ++
 src/setjmp/x32/setjmp.s            |  22 ++
 src/signal/x32/restore.s           |   8 +
 src/signal/x32/sigsetjmp.s         |  14 +
 src/thread/cancel_dummy.c          |   9 +-
 src/thread/cancel_impl.c           |  12 +-
 src/thread/x32/__set_thread_area.s |  10 +
 src/thread/x32/__unmapself.s       |  10 +
 src/thread/x32/clone.s             |  28 ++
 src/thread/x32/syscall_cp.s        |  23 ++
 53 files changed, 2286 insertions(+), 34 deletions(-)
 create mode 100644 arch/x32/atomic.h
 create mode 100644 arch/x32/bits/alltypes.h.in
 create mode 100644 arch/x32/bits/endian.h
 create mode 100644 arch/x32/bits/errno.h
 create mode 100644 arch/x32/bits/fcntl.h
 create mode 100644 arch/x32/bits/fenv.h
 create mode 100644 arch/x32/bits/float.h
 create mode 100644 arch/x32/bits/io.h
 create mode 100644 arch/x32/bits/ioctl.h
 create mode 100644 arch/x32/bits/ipc.h
 create mode 100644 arch/x32/bits/limits.h
 create mode 100644 arch/x32/bits/mman.h
 create mode 100644 arch/x32/bits/msg.h
 create mode 100644 arch/x32/bits/posix.h
 create mode 100644 arch/x32/bits/reg.h
 create mode 100644 arch/x32/bits/setjmp.h
 create mode 100644 arch/x32/bits/shm.h
 create mode 100644 arch/x32/bits/signal.h
 create mode 100644 arch/x32/bits/socket.h
 create mode 100644 arch/x32/bits/stat.h
 create mode 100644 arch/x32/bits/statfs.h
 create mode 100644 arch/x32/bits/stdarg.h
 create mode 100644 arch/x32/bits/stdint.h
 create mode 100644 arch/x32/bits/syscall.h
 create mode 100644 arch/x32/bits/termios.h
 create mode 100644 arch/x32/bits/user.h
 create mode 100644 arch/x32/crt_arch.h
 create mode 100644 arch/x32/pthread_arch.h
 create mode 100644 arch/x32/reloc.h
 create mode 100644 arch/x32/syscall_arch.h
 create mode 100644 crt/x32/Scrt1.s
 create mode 100644 crt/x32/crt1.s
 create mode 100644 crt/x32/crti.s
 create mode 100644 crt/x32/crtn.s
 create mode 100644 src/internal/x32/syscall.s
 create mode 100644 src/ldso/x32/dlsym.s
 create mode 100644 src/ldso/x32/start.s
 create mode 100644 src/process/x32/vfork.s
 create mode 100644 src/setjmp/x32/longjmp.s
 create mode 100644 src/setjmp/x32/setjmp.s
 create mode 100644 src/signal/x32/restore.s
 create mode 100644 src/signal/x32/sigsetjmp.s
 create mode 100644 src/thread/x32/__set_thread_area.s
 create mode 100644 src/thread/x32/__unmapself.s
 create mode 100644 src/thread/x32/clone.s
 create mode 100644 src/thread/x32/syscall_cp.s

diff --git a/arch/x32/atomic.h b/arch/x32/atomic.h
new file mode 100644
index 0000000..e304bcc
--- /dev/null
+++ b/arch/x32/atomic.h
@@ -0,0 +1,127 @@
+#ifndef _INTERNAL_ATOMIC_H
+#define _INTERNAL_ATOMIC_H
+
+#include <stdint.h>
+
+static inline int a_ctz_64(uint64_t x)
+{
+	long long r;
+	__asm__( "bsf %1,%0" : "=r"(r) : "r"(x) );
+	return r;
+}
+
+static inline int a_ctz_l(unsigned long x)
+{
+	long r;
+	__asm__( "bsf %1,%0" : "=r"(r) : "r"(x) );
+	return r;
+}
+
+static inline void a_and_64(volatile uint64_t *p, uint64_t v)
+{
+	__asm__( "lock ; andq %1, %0 ; "
+			 : "=m"(*(long long *)p) : "r"(v) : "memory" );
+}
+
+static inline void a_or_64(volatile uint64_t *p, uint64_t v)
+{
+	__asm__( "lock ; orq %1, %0"
+			 : "=m"(*(long long *)p) : "r"(v) : "memory" );
+}
+
+static inline void a_store_l(volatile void *p, long x)
+{
+	__asm__( "movl %1, %0" : "=m"(*(long *)p) : "r"(x) : "memory" );
+}
+
+static inline void a_or_l(volatile void *p, long v)
+{
+	__asm__( "lock ; or %1, %0"
+		: "=m"(*(long *)p) : "r"(v) : "memory" );
+}
+
+static inline void *a_cas_p(volatile void *p, void *t, void *s)
+{
+	__asm__( "lock ; cmpxchg %3, %1"
+		: "=a"(t), "=m"(*(long *)p) : "a"(t), "r"(s) : "memory" );
+	return t;
+}
+
+static inline long a_cas_l(volatile void *p, long t, long s)
+{
+	__asm__( "lock ; cmpxchg %3, %1"
+		: "=a"(t), "=m"(*(long *)p) : "a"(t), "r"(s) : "memory" );
+	return t;
+}
+
+static inline int a_cas(volatile int *p, int t, int s)
+{
+	__asm__( "lock ; cmpxchgl %3, %1"
+		: "=a"(t), "=m"(*p) : "a"(t), "r"(s) : "memory" );
+	return t;
+}
+
+static inline void *a_swap_p(void *volatile *x, void *v)
+{
+	__asm__( "xchg %0, %1" : "=r"(v), "=m"(*(void **)x) : "0"(v) : "memory" );
+	return v;
+}
+static inline long a_swap_l(volatile void *x, long v)
+{
+	__asm__( "xchg %0, %1" : "=r"(v), "=m"(*(long *)x) : "0"(v) : "memory" );
+	return v;
+}
+
+static inline void a_or(volatile void *p, int v)
+{
+	__asm__( "lock ; orl %1, %0"
+		: "=m"(*(int *)p) : "r"(v) : "memory" );
+}
+
+static inline void a_and(volatile void *p, int v)
+{
+	__asm__( "lock ; andl %1, %0"
+		: "=m"(*(int *)p) : "r"(v) : "memory" );
+}
+
+static inline int a_swap(volatile int *x, int v)
+{
+	__asm__( "xchg %0, %1" : "=r"(v), "=m"(*x) : "0"(v) : "memory" );
+	return v;
+}
+
+#define a_xchg a_swap
+
+static inline int a_fetch_add(volatile int *x, int v)
+{
+	__asm__( "lock ; xadd %0, %1" : "=r"(v), "=m"(*x) : "0"(v) : "memory" );
+	return v;
+}
+
+static inline void a_inc(volatile int *x)
+{
+	__asm__( "lock ; incl %0" : "=m"(*x) : "m"(*x) : "memory" );
+}
+
+static inline void a_dec(volatile int *x)
+{
+	__asm__( "lock ; decl %0" : "=m"(*x) : "m"(*x) : "memory" );
+}
+
+static inline void a_store(volatile int *p, int x)
+{
+	__asm__( "movl %1, %0" : "=m"(*p) : "r"(x) : "memory" );
+}
+
+static inline void a_spin()
+{
+	__asm__ __volatile__( "pause" : : : "memory" );
+}
+
+static inline void a_crash()
+{
+	__asm__ __volatile__( "hlt" : : : "memory" );
+}
+
+
+#endif
diff --git a/arch/x32/bits/alltypes.h.in b/arch/x32/bits/alltypes.h.in
new file mode 100644
index 0000000..1b907a3
--- /dev/null
+++ b/arch/x32/bits/alltypes.h.in
@@ -0,0 +1,28 @@
+#define _Addr long
+#define _Int64 long long
+#define _Reg long long
+
+TYPEDEF __builtin_va_list va_list;
+TYPEDEF __builtin_va_list __isoc_va_list;
+
+#ifndef __cplusplus
+TYPEDEF long wchar_t;
+#endif
+TYPEDEF unsigned wint_t;
+
+#if defined(__FLT_EVAL_METHOD__) && __FLT_EVAL_METHOD__ == 2
+TYPEDEF long double float_t;
+TYPEDEF long double double_t;
+#else
+TYPEDEF float float_t;
+TYPEDEF double double_t;
+#endif
+
+TYPEDEF long long time_t;
+TYPEDEF long long suseconds_t;
+
+TYPEDEF struct { union { int __i[14]; unsigned long __s[7]; } __u; } pthread_attr_t;
+TYPEDEF struct { union { int __i[10]; void *__p[5]; } __u; } pthread_mutex_t;
+TYPEDEF struct { union { int __i[12]; void *__p[6]; } __u; } pthread_cond_t;
+TYPEDEF struct { union { int __i[14]; void *__p[7]; } __u; } pthread_rwlock_t;
+TYPEDEF struct { union { int __i[8]; void *__p[4]; } __u; } pthread_barrier_t;
diff --git a/arch/x32/bits/endian.h b/arch/x32/bits/endian.h
new file mode 100644
index 0000000..172c338
--- /dev/null
+++ b/arch/x32/bits/endian.h
@@ -0,0 +1 @@
+#define __BYTE_ORDER __LITTLE_ENDIAN
diff --git a/arch/x32/bits/errno.h b/arch/x32/bits/errno.h
new file mode 100644
index 0000000..d2e1eee
--- /dev/null
+++ b/arch/x32/bits/errno.h
@@ -0,0 +1,134 @@
+#define EPERM            1
+#define ENOENT           2
+#define ESRCH            3
+#define EINTR            4
+#define EIO              5
+#define ENXIO            6
+#define E2BIG            7
+#define ENOEXEC          8
+#define EBADF            9
+#define ECHILD          10
+#define EAGAIN          11
+#define ENOMEM          12
+#define EACCES          13
+#define EFAULT          14
+#define ENOTBLK         15
+#define EBUSY           16
+#define EEXIST          17
+#define EXDEV           18
+#define ENODEV          19
+#define ENOTDIR         20
+#define EISDIR          21
+#define EINVAL          22
+#define ENFILE          23
+#define EMFILE          24
+#define ENOTTY          25
+#define ETXTBSY         26
+#define EFBIG           27
+#define ENOSPC          28
+#define ESPIPE          29
+#define EROFS           30
+#define EMLINK          31
+#define EPIPE           32
+#define EDOM            33
+#define ERANGE          34
+#define EDEADLK         35
+#define ENAMETOOLONG    36
+#define ENOLCK          37
+#define ENOSYS          38
+#define ENOTEMPTY       39
+#define ELOOP           40
+#define EWOULDBLOCK     EAGAIN
+#define ENOMSG          42
+#define EIDRM           43
+#define ECHRNG          44
+#define EL2NSYNC        45
+#define EL3HLT          46
+#define EL3RST          47
+#define ELNRNG          48
+#define EUNATCH         49
+#define ENOCSI          50
+#define EL2HLT          51
+#define EBADE           52
+#define EBADR           53
+#define EXFULL          54
+#define ENOANO          55
+#define EBADRQC         56
+#define EBADSLT         57
+#define EDEADLOCK       EDEADLK
+#define EBFONT          59
+#define ENOSTR          60
+#define ENODATA         61
+#define ETIME           62
+#define ENOSR           63
+#define ENONET          64
+#define ENOPKG          65
+#define EREMOTE         66
+#define ENOLINK         67
+#define EADV            68
+#define ESRMNT          69
+#define ECOMM           70
+#define EPROTO          71
+#define EMULTIHOP       72
+#define EDOTDOT         73
+#define EBADMSG         74
+#define EOVERFLOW       75
+#define ENOTUNIQ        76
+#define EBADFD          77
+#define EREMCHG         78
+#define ELIBACC         79
+#define ELIBBAD         80
+#define ELIBSCN         81
+#define ELIBMAX         82
+#define ELIBEXEC        83
+#define EILSEQ          84
+#define ERESTART        85
+#define ESTRPIPE        86
+#define EUSERS          87
+#define ENOTSOCK        88
+#define EDESTADDRREQ    89
+#define EMSGSIZE        90
+#define EPROTOTYPE      91
+#define ENOPROTOOPT     92
+#define EPROTONOSUPPORT 93
+#define ESOCKTNOSUPPORT 94
+#define EOPNOTSUPP      95
+#define ENOTSUP         EOPNOTSUPP
+#define EPFNOSUPPORT    96
+#define EAFNOSUPPORT    97
+#define EADDRINUSE      98
+#define EADDRNOTAVAIL   99
+#define ENETDOWN        100
+#define ENETUNREACH     101
+#define ENETRESET       102
+#define ECONNABORTED    103
+#define ECONNRESET      104
+#define ENOBUFS         105
+#define EISCONN         106
+#define ENOTCONN        107
+#define ESHUTDOWN       108
+#define ETOOMANYREFS    109
+#define ETIMEDOUT       110
+#define ECONNREFUSED    111
+#define EHOSTDOWN       112
+#define EHOSTUNREACH    113
+#define EALREADY        114
+#define EINPROGRESS     115
+#define ESTALE          116
+#define EUCLEAN         117
+#define ENOTNAM         118
+#define ENAVAIL         119
+#define EISNAM          120
+#define EREMOTEIO       121
+#define EDQUOT          122
+#define ENOMEDIUM       123
+#define EMEDIUMTYPE     124
+#define ECANCELED       125
+#define ENOKEY          126
+#define EKEYEXPIRED     127
+#define EKEYREVOKED     128
+#define EKEYREJECTED    129
+#define EOWNERDEAD      130
+#define ENOTRECOVERABLE 131
+#define ERFKILL         132
+#define EHWPOISON       133
diff --git a/arch/x32/bits/fcntl.h b/arch/x32/bits/fcntl.h
new file mode 100644
index 0000000..9977713
--- /dev/null
+++ b/arch/x32/bits/fcntl.h
@@ -0,0 +1,39 @@
+#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       0
+#define O_NOATIME  01000000
+#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_SETOWN 8
+#define F_GETOWN 9
+#define F_SETSIG 10
+#define F_GETSIG 11
+
+#define F_GETLK 5
+#define F_SETLK 6
+#define F_SETLKW 7
+
+#define F_SETOWN_EX 15
+#define F_GETOWN_EX 16
+
+#define F_GETOWNER_UIDS 17
diff --git a/arch/x32/bits/fenv.h b/arch/x32/bits/fenv.h
new file mode 100644
index 0000000..24df041
--- /dev/null
+++ b/arch/x32/bits/fenv.h
@@ -0,0 +1,34 @@
+#define FE_INVALID    1
+#define __FE_DENORM   2
+#define FE_DIVBYZERO  4
+#define FE_OVERFLOW   8
+#define FE_UNDERFLOW  16
+#define FE_INEXACT    32
+
+#define FE_ALL_EXCEPT 63
+
+#define FE_TONEAREST  0
+#define FE_DOWNWARD   0x400
+#define FE_UPWARD     0x800
+#define FE_TOWARDZERO 0xc00
+
+typedef unsigned short fexcept_t;
+
+typedef struct {
+	unsigned short __control_word;
+	unsigned short __unused1;
+	unsigned short __status_word;
+	unsigned short __unused2;
+	unsigned short __tags;
+	unsigned short __unused3;
+	unsigned int __eip;
+	unsigned short __cs_selector;
+	unsigned int __opcode:11;
+	unsigned int __unused4:5;
+	unsigned int __data_offset;
+	unsigned short __data_selector;
+	unsigned short __unused5;
+	unsigned int __mxcsr;
+} fenv_t;
+
+#define FE_DFL_ENV      ((const fenv_t *) -1)
diff --git a/arch/x32/bits/float.h b/arch/x32/bits/float.h
new file mode 100644
index 0000000..9ea2991
--- /dev/null
+++ b/arch/x32/bits/float.h
@@ -0,0 +1,21 @@
+#define FLT_ROUNDS 1
+#ifdef __FLT_EVAL_METHOD__
+#define FLT_EVAL_METHOD __FLT_EVAL_METHOD__
+#else
+#define FLT_EVAL_METHOD 0
+#endif
+
+#define LDBL_TRUE_MIN 3.6451995318824746025e-4951L
+#define LDBL_MIN     3.3621031431120935063e-4932L
+#define LDBL_MAX     1.1897314953572317650e+4932L
+#define LDBL_EPSILON 1.0842021724855044340e-19L
+
+#define LDBL_MANT_DIG 64
+#define LDBL_MIN_EXP (-16381)
+#define LDBL_MAX_EXP 16384
+
+#define LDBL_DIG 18
+#define LDBL_MIN_10_EXP (-4931)
+#define LDBL_MAX_10_EXP 4932
+
+#define DECIMAL_DIG 21
diff --git a/arch/x32/bits/io.h b/arch/x32/bits/io.h
new file mode 100644
index 0000000..dd5bddc
--- /dev/null
+++ b/arch/x32/bits/io.h
@@ -0,0 +1,77 @@
+static __inline void outb(unsigned char __val, unsigned short __port)
+{
+	__asm__ volatile ("outb %0,%1" : : "a" (__val), "dN" (__port));
+}
+
+static __inline void outw(unsigned short __val, unsigned short __port)
+{
+	__asm__ volatile ("outw %0,%1" : : "a" (__val), "dN" (__port));
+}
+
+static __inline void outl(unsigned int __val, unsigned short __port)
+{
+	__asm__ volatile ("outl %0,%1" : : "a" (__val), "dN" (__port));
+}
+
+static __inline unsigned char inb(unsigned short __port)
+{
+	unsigned char __val;
+	__asm__ volatile ("inb %1,%0" : "=a" (__val) : "dN" (__port));
+	return __val;
+}
+
+static __inline unsigned short inw(unsigned short __port)
+{
+	unsigned short __val;
+	__asm__ volatile ("inw %1,%0" : "=a" (__val) : "dN" (__port));
+	return __val;
+}
+
+static __inline unsigned int inl(unsigned short __port)
+{
+	unsigned int __val;
+	__asm__ volatile ("inl %1,%0" : "=a" (__val) : "dN" (__port));
+	return __val;
+}
+
+static __inline void outsb(unsigned short __port, const void *__buf, unsigned long __n)
+{
+	__asm__ volatile ("cld; rep; outsb"
+		      : "+S" (__buf), "+c" (__n)
+		      : "d" (__port));
+}
+
+static __inline void outsw(unsigned short __port, const void *__buf, unsigned long __n)
+{
+	__asm__ volatile ("cld; rep; outsw"
+		      : "+S" (__buf), "+c" (__n)
+		      : "d" (__port));
+}
+
+static __inline void outsl(unsigned short __port, const void *__buf, unsigned long __n)
+{
+	__asm__ volatile ("cld; rep; outsl"
+		      : "+S" (__buf), "+c"(__n)
+		      : "d" (__port));
+}
+
+static __inline void insb(unsigned short __port, void *__buf, unsigned long __n)
+{
+	__asm__ volatile ("cld; rep; insb"
+		      : "+D" (__buf), "+c" (__n)
+		      : "d" (__port));
+}
+
+static __inline void insw(unsigned short __port, void *__buf, unsigned long __n)
+{
+	__asm__ volatile ("cld; rep; insw"
+		      : "+D" (__buf), "+c" (__n)
+		      : "d" (__port));
+}
+
+static __inline void insl(unsigned short __port, void *__buf, unsigned long __n)
+{
+	__asm__ volatile ("cld; rep; insl"
+		      : "+D" (__buf), "+c" (__n)
+		      : "d" (__port));
+}
diff --git a/arch/x32/bits/ioctl.h b/arch/x32/bits/ioctl.h
new file mode 100644
index 0000000..77a9455
--- /dev/null
+++ b/arch/x32/bits/ioctl.h
@@ -0,0 +1,197 @@
+#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 TIOCGHAYESESP   0x545E
+#define TIOCSHAYESESP   0x545F
+#define FIOQSIZE	0x5460
+
+#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/x32/bits/ipc.h b/arch/x32/bits/ipc.h
new file mode 100644
index 0000000..6e604ce
--- /dev/null
+++ b/arch/x32/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;
+	int __ipc_perm_seq;
+	long long __pad1;
+	long long __pad2;
+};
+
+#define IPC_64 0
diff --git a/arch/x32/bits/limits.h b/arch/x32/bits/limits.h
new file mode 100644
index 0000000..65a3dd6
--- /dev/null
+++ b/arch/x32/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 32
+#endif
+
+#define LONG_MAX  0x7fffffffL
+#define LLONG_MAX  0x7fffffffffffffffLL
diff --git a/arch/x32/bits/mman.h b/arch/x32/bits/mman.h
new file mode 100644
index 0000000..dcab47a
--- /dev/null
+++ b/arch/x32/bits/mman.h
@@ -0,0 +1,62 @@
+#define MAP_FAILED ((void *) -1)
+
+#define	PROT_NONE      0
+#define	PROT_READ      1
+#define	PROT_WRITE     2
+#define	PROT_EXEC      4
+#define PROT_GROWSDOWN  0x01000000
+#define PROT_GROWSUP    0x02000000
+
+#define	MAP_SHARED     0x01
+#define	MAP_PRIVATE    0x02
+#define	MAP_FIXED      0x10
+
+#define MAP_TYPE       0x0f
+#define MAP_FILE       0x00
+#define MAP_ANON       0x20
+#define MAP_ANONYMOUS  MAP_ANON
+#define MAP_32BIT      0x40
+#define MAP_NORESERVE  0x4000
+#define MAP_GROWSDOWN  0x0100
+#define MAP_DENYWRITE  0x0800
+#define MAP_EXECUTABLE 0x1000
+#define MAP_LOCKED     0x2000
+#define MAP_POPULATE   0x8000
+#define MAP_NONBLOCK   0x10000
+#define MAP_STACK      0x20000
+#define MAP_HUGETLB    0x40000
+
+#define POSIX_MADV_NORMAL       0
+#define POSIX_MADV_RANDOM       1
+#define POSIX_MADV_SEQUENTIAL   2
+#define POSIX_MADV_WILLNEED     3
+#define POSIX_MADV_DONTNEED     0
+
+#define MS_ASYNC        1
+#define MS_INVALIDATE   2
+#define MS_SYNC         4
+
+#define MCL_CURRENT     1
+#define MCL_FUTURE      2
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+#define MADV_NORMAL      0
+#define MADV_RANDOM      1
+#define MADV_SEQUENTIAL  2
+#define MADV_WILLNEED    3
+#define MADV_DONTNEED    4
+#define MADV_REMOVE      9
+#define MADV_DONTFORK    10
+#define MADV_DOFORK      11
+#define MADV_MERGEABLE   12
+#define MADV_UNMERGEABLE 13
+#define MADV_HUGEPAGE    14
+#define MADV_NOHUGEPAGE  15
+#define MADV_DONTDUMP    16
+#define MADV_DODUMP      17
+#define MADV_HWPOISON    100
+#define MADV_SOFT_OFFLINE 101
+
+#define MREMAP_MAYMOVE  1
+#define MREMAP_FIXED    2
+#endif
diff --git a/arch/x32/bits/msg.h b/arch/x32/bits/msg.h
new file mode 100644
index 0000000..c52e92c
--- /dev/null
+++ b/arch/x32/bits/msg.h
@@ -0,0 +1,13 @@
+struct msqid_ds
+{
+	struct ipc_perm msg_perm;
+	time_t msg_stime;
+	time_t msg_rtime;
+	time_t msg_ctime;
+	unsigned long long msg_cbytes;
+	msgqnum_t msg_qnum;
+	msglen_t msg_qbytes;
+	pid_t msg_lspid;
+	pid_t msg_lrpid;
+	unsigned long long __unused[2];
+};
diff --git a/arch/x32/bits/posix.h b/arch/x32/bits/posix.h
new file mode 100644
index 0000000..c37b94c
--- /dev/null
+++ b/arch/x32/bits/posix.h
@@ -0,0 +1,2 @@
+#define _POSIX_V6_LP64_OFF64  1
+#define _POSIX_V7_LP64_OFF64  1
diff --git a/arch/x32/bits/reg.h b/arch/x32/bits/reg.h
new file mode 100644
index 0000000..5faaef1
--- /dev/null
+++ b/arch/x32/bits/reg.h
@@ -0,0 +1,29 @@
+#undef __WORDSIZE
+#define __WORDSIZE 32
+#define R15    0
+#define R14    1
+#define R13    2
+#define R12    3
+#define RBP    4
+#define RBX    5
+#define R11    6
+#define R10    7
+#define R9     8
+#define R8     9
+#define RAX    10
+#define RCX    11
+#define RDX    12
+#define RSI    13
+#define RDI    14
+#define ORIG_RAX 15
+#define RIP    16
+#define CS     17
+#define EFLAGS 18
+#define RSP    19
+#define SS     20
+#define FS_BASE 21
+#define GS_BASE 22
+#define DS     23
+#define ES     24
+#define FS     25
+#define GS     26
diff --git a/arch/x32/bits/setjmp.h b/arch/x32/bits/setjmp.h
new file mode 100644
index 0000000..a9262a6
--- /dev/null
+++ b/arch/x32/bits/setjmp.h
@@ -0,0 +1 @@
+typedef unsigned long long __jmp_buf[8];
diff --git a/arch/x32/bits/shm.h b/arch/x32/bits/shm.h
new file mode 100644
index 0000000..3a7636f
--- /dev/null
+++ b/arch/x32/bits/shm.h
@@ -0,0 +1,15 @@
+#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 long shm_nattch;
+	unsigned long long __pad1;
+	unsigned long long __pad2;
+};
diff --git a/arch/x32/bits/signal.h b/arch/x32/bits/signal.h
new file mode 100644
index 0000000..ecbb813
--- /dev/null
+++ b/arch/x32/bits/signal.h
@@ -0,0 +1,119 @@
+#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \
+ || defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+
+#ifdef _GNU_SOURCE
+#define REG_R8          0
+#define REG_R9          1
+#define REG_R10         2
+#define REG_R11         3
+#define REG_R12         4
+#define REG_R13         5
+#define REG_R14         6
+#define REG_R15         7
+#define REG_RDI         8
+#define REG_RSI         9
+#define REG_RBP         10
+#define REG_RBX         11
+#define REG_RDX         12
+#define REG_RAX         13
+#define REG_RCX         14
+#define REG_RSP         15
+#define REG_RIP         16
+#define REG_EFL         17
+#define REG_CSGSFS      18
+#define REG_ERR         19
+#define REG_TRAPNO      20
+#define REG_OLDMASK     21
+#define REG_CR2         22
+#endif
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+typedef long long greg_t, gregset_t[23];
+typedef struct _fpstate {
+	unsigned short cwd, swd, ftw, fop;
+	unsigned long long rip, rdp;
+	unsigned mxcsr, mxcr_mask;
+	struct {
+		unsigned short significand[4], exponent, padding[3];
+	} _st[8];
+	struct {
+		unsigned element[4];
+	} _xmm[16];
+	unsigned padding[24];
+} *fpregset_t;
+struct sigcontext {
+	unsigned long long r8, r9, r10, r11, r12, r13, r14, r15;
+	unsigned long long rdi, rsi, rbp, rbx, rdx, rax, rcx, rsp, rip, eflags;
+	unsigned short cs, gs, fs, __pad0;
+	unsigned long long err, trapno, oldmask, cr2;
+	struct _fpstate *fpstate;
+	unsigned long long __reserved1[8];
+};
+typedef struct {
+	gregset_t gregs;
+	fpregset_t fpregs;
+	unsigned long long __reserved1[8];
+} mcontext_t;
+#else
+typedef struct {
+	unsigned long long __space[32];
+} mcontext_t;
+#endif
+
+typedef struct __ucontext {
+	unsigned long uc_flags;
+	struct __ucontext *uc_link;
+	stack_t uc_stack;
+	mcontext_t uc_mcontext;
+	sigset_t uc_sigmask;
+	unsigned long long __fpregs_mem[64];
+} ucontext_t;
+
+#define SA_NOCLDSTOP  1
+#define SA_NOCLDWAIT  2
+#define SA_SIGINFO    4
+#define SA_ONSTACK    0x08000000
+#define SA_RESTART    0x10000000
+#define SA_NODEFER    0x40000000
+#define SA_RESETHAND  0x80000000
+#define SA_RESTORER   0x04000000
+
+#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   29
+#define SIGPWR    30
+#define SIGSYS    31
+#define SIGUNUSED SIGSYS
+
+#define _NSIG 65
+
diff --git a/arch/x32/bits/socket.h b/arch/x32/bits/socket.h
new file mode 100644
index 0000000..a90c4ca
--- /dev/null
+++ b/arch/x32/bits/socket.h
@@ -0,0 +1,18 @@
+struct msghdr
+{
+	void *msg_name;
+	socklen_t msg_namelen;
+	struct iovec *msg_iov;
+	int msg_iovlen, __pad1;
+	void *msg_control;
+	socklen_t msg_controllen, __pad2;
+	int msg_flags;
+};
+
+struct cmsghdr
+{
+	socklen_t cmsg_len;
+	int __pad1;
+	int cmsg_level;
+	int cmsg_type;
+};
diff --git a/arch/x32/bits/stat.h b/arch/x32/bits/stat.h
new file mode 100644
index 0000000..2145796
--- /dev/null
+++ b/arch/x32/bits/stat.h
@@ -0,0 +1,22 @@
+/* copied from kernel definition, but with padding replaced
+ * by the corresponding correctly-sized userspace types. */
+
+struct stat {
+	unsigned long st_dev;
+	ino_t st_ino;
+	nlink_t st_nlink;
+
+	mode_t st_mode;
+	uid_t st_uid;
+	gid_t st_gid;
+	unsigned int    __pad0;
+	dev_t st_rdev;
+	off_t st_size;
+	blksize_t st_blksize;
+	blkcnt_t st_blocks;
+
+	struct timespec st_atim;
+	struct timespec st_mtim;
+	struct timespec st_ctim;
+	long __unused[3];
+};
diff --git a/arch/x32/bits/statfs.h b/arch/x32/bits/statfs.h
new file mode 100644
index 0000000..f103f4e
--- /dev/null
+++ b/arch/x32/bits/statfs.h
@@ -0,0 +1,7 @@
+struct statfs {
+	unsigned long f_type, f_bsize;
+	fsblkcnt_t f_blocks, f_bfree, f_bavail;
+	fsfilcnt_t f_files, f_ffree;
+	fsid_t f_fsid;
+	unsigned long f_namelen, f_frsize, f_flags, f_spare[4];
+};
diff --git a/arch/x32/bits/stdarg.h b/arch/x32/bits/stdarg.h
new file mode 100644
index 0000000..fde3781
--- /dev/null
+++ b/arch/x32/bits/stdarg.h
@@ -0,0 +1,4 @@
+#define va_start(v,l)   __builtin_va_start(v,l)
+#define va_end(v)       __builtin_va_end(v)
+#define va_arg(v,l)     __builtin_va_arg(v,l)
+#define va_copy(d,s)    __builtin_va_copy(d,s)
diff --git a/arch/x32/bits/stdint.h b/arch/x32/bits/stdint.h
new file mode 100644
index 0000000..d1b2712
--- /dev/null
+++ b/arch/x32/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      INT32_MIN
+#define INTPTR_MAX      INT32_MAX
+#define UINTPTR_MAX     UINT32_MAX
+#define PTRDIFF_MIN     INT32_MIN
+#define PTRDIFF_MAX     INT32_MAX
+#define SIZE_MAX        UINT32_MAX
diff --git a/arch/x32/bits/syscall.h b/arch/x32/bits/syscall.h
new file mode 100644
index 0000000..95e2d2f
--- /dev/null
+++ b/arch/x32/bits/syscall.h
@@ -0,0 +1,634 @@
+#define __X32_SYSCALL_BIT        0x40000000
+#define __NR_read (__X32_SYSCALL_BIT + 0)
+#define __NR_write (__X32_SYSCALL_BIT + 1)
+#define __NR_open (__X32_SYSCALL_BIT + 2)
+#define __NR_close (__X32_SYSCALL_BIT + 3)
+#define __NR_stat (__X32_SYSCALL_BIT + 4)
+#define __NR_fstat (__X32_SYSCALL_BIT + 5)
+#define __NR_lstat (__X32_SYSCALL_BIT + 6)
+#define __NR_poll (__X32_SYSCALL_BIT + 7)
+#define __NR_lseek (__X32_SYSCALL_BIT + 8)
+#define __NR_mmap (__X32_SYSCALL_BIT + 9)
+#define __NR_mprotect (__X32_SYSCALL_BIT + 10)
+#define __NR_munmap (__X32_SYSCALL_BIT + 11)
+#define __NR_brk (__X32_SYSCALL_BIT + 12)
+#define __NR_rt_sigprocmask (__X32_SYSCALL_BIT + 14)
+#define __NR_pread64 (__X32_SYSCALL_BIT + 17)
+#define __NR_pwrite64 (__X32_SYSCALL_BIT + 18)
+#define __NR_access (__X32_SYSCALL_BIT + 21)
+#define __NR_pipe (__X32_SYSCALL_BIT + 22)
+#define __NR_select (__X32_SYSCALL_BIT + 23)
+#define __NR_sched_yield (__X32_SYSCALL_BIT + 24)
+#define __NR_mremap (__X32_SYSCALL_BIT + 25)
+#define __NR_msync (__X32_SYSCALL_BIT + 26)
+#define __NR_mincore (__X32_SYSCALL_BIT + 27)
+#define __NR_madvise (__X32_SYSCALL_BIT + 28)
+#define __NR_shmget (__X32_SYSCALL_BIT + 29)
+#define __NR_shmat (__X32_SYSCALL_BIT + 30)
+#define __NR_shmctl (__X32_SYSCALL_BIT + 31)
+#define __NR_dup (__X32_SYSCALL_BIT + 32)
+#define __NR_dup2 (__X32_SYSCALL_BIT + 33)
+#define __NR_pause (__X32_SYSCALL_BIT + 34)
+#define __NR_nanosleep (__X32_SYSCALL_BIT + 35)
+#define __NR_getitimer (__X32_SYSCALL_BIT + 36)
+#define __NR_alarm (__X32_SYSCALL_BIT + 37)
+#define __NR_setitimer (__X32_SYSCALL_BIT + 38)
+#define __NR_getpid (__X32_SYSCALL_BIT + 39)
+#define __NR_sendfile (__X32_SYSCALL_BIT + 40)
+#define __NR_socket (__X32_SYSCALL_BIT + 41)
+#define __NR_connect (__X32_SYSCALL_BIT + 42)
+#define __NR_accept (__X32_SYSCALL_BIT + 43)
+#define __NR_sendto (__X32_SYSCALL_BIT + 44)
+#define __NR_shutdown (__X32_SYSCALL_BIT + 48)
+#define __NR_bind (__X32_SYSCALL_BIT + 49)
+#define __NR_listen (__X32_SYSCALL_BIT + 50)
+#define __NR_getsockname (__X32_SYSCALL_BIT + 51)
+#define __NR_getpeername (__X32_SYSCALL_BIT + 52)
+#define __NR_socketpair (__X32_SYSCALL_BIT + 53)
+#define __NR_clone (__X32_SYSCALL_BIT + 56)
+#define __NR_fork (__X32_SYSCALL_BIT + 57)
+#define __NR_vfork (__X32_SYSCALL_BIT + 58)
+#define __NR_exit (__X32_SYSCALL_BIT + 60)
+#define __NR_wait4 (__X32_SYSCALL_BIT + 61)
+#define __NR_kill (__X32_SYSCALL_BIT + 62)
+#define __NR_uname (__X32_SYSCALL_BIT + 63)
+#define __NR_semget (__X32_SYSCALL_BIT + 64)
+#define __NR_semop (__X32_SYSCALL_BIT + 65)
+#define __NR_semctl (__X32_SYSCALL_BIT + 66)
+#define __NR_shmdt (__X32_SYSCALL_BIT + 67)
+#define __NR_msgget (__X32_SYSCALL_BIT + 68)
+#define __NR_msgsnd (__X32_SYSCALL_BIT + 69)
+#define __NR_msgrcv (__X32_SYSCALL_BIT + 70)
+#define __NR_msgctl (__X32_SYSCALL_BIT + 71)
+#define __NR_fcntl (__X32_SYSCALL_BIT + 72)
+#define __NR_flock (__X32_SYSCALL_BIT + 73)
+#define __NR_fsync (__X32_SYSCALL_BIT + 74)
+#define __NR_fdatasync (__X32_SYSCALL_BIT + 75)
+#define __NR_truncate (__X32_SYSCALL_BIT + 76)
+#define __NR_ftruncate (__X32_SYSCALL_BIT + 77)
+#define __NR_getdents (__X32_SYSCALL_BIT + 78)
+#define __NR_getcwd (__X32_SYSCALL_BIT + 79)
+#define __NR_chdir (__X32_SYSCALL_BIT + 80)
+#define __NR_fchdir (__X32_SYSCALL_BIT + 81)
+#define __NR_rename (__X32_SYSCALL_BIT + 82)
+#define __NR_mkdir (__X32_SYSCALL_BIT + 83)
+#define __NR_rmdir (__X32_SYSCALL_BIT + 84)
+#define __NR_creat (__X32_SYSCALL_BIT + 85)
+#define __NR_link (__X32_SYSCALL_BIT + 86)
+#define __NR_unlink (__X32_SYSCALL_BIT + 87)
+#define __NR_symlink (__X32_SYSCALL_BIT + 88)
+#define __NR_readlink (__X32_SYSCALL_BIT + 89)
+#define __NR_chmod (__X32_SYSCALL_BIT + 90)
+#define __NR_fchmod (__X32_SYSCALL_BIT + 91)
+#define __NR_chown (__X32_SYSCALL_BIT + 92)
+#define __NR_fchown (__X32_SYSCALL_BIT + 93)
+#define __NR_lchown (__X32_SYSCALL_BIT + 94)
+#define __NR_umask (__X32_SYSCALL_BIT + 95)
+#define __NR_gettimeofday (__X32_SYSCALL_BIT + 96)
+#define __NR_getrlimit (__X32_SYSCALL_BIT + 97)
+#define __NR_getrusage (__X32_SYSCALL_BIT + 98)
+#define __NR_sysinfo (__X32_SYSCALL_BIT + 99)
+#define __NR_times (__X32_SYSCALL_BIT + 100)
+#define __NR_getuid (__X32_SYSCALL_BIT + 102)
+#define __NR_syslog (__X32_SYSCALL_BIT + 103)
+#define __NR_getgid (__X32_SYSCALL_BIT + 104)
+#define __NR_setuid (__X32_SYSCALL_BIT + 105)
+#define __NR_setgid (__X32_SYSCALL_BIT + 106)
+#define __NR_geteuid (__X32_SYSCALL_BIT + 107)
+#define __NR_getegid (__X32_SYSCALL_BIT + 108)
+#define __NR_setpgid (__X32_SYSCALL_BIT + 109)
+#define __NR_getppid (__X32_SYSCALL_BIT + 110)
+#define __NR_getpgrp (__X32_SYSCALL_BIT + 111)
+#define __NR_setsid (__X32_SYSCALL_BIT + 112)
+#define __NR_setreuid (__X32_SYSCALL_BIT + 113)
+#define __NR_setregid (__X32_SYSCALL_BIT + 114)
+#define __NR_getgroups (__X32_SYSCALL_BIT + 115)
+#define __NR_setgroups (__X32_SYSCALL_BIT + 116)
+#define __NR_setresuid (__X32_SYSCALL_BIT + 117)
+#define __NR_getresuid (__X32_SYSCALL_BIT + 118)
+#define __NR_setresgid (__X32_SYSCALL_BIT + 119)
+#define __NR_getresgid (__X32_SYSCALL_BIT + 120)
+#define __NR_getpgid (__X32_SYSCALL_BIT + 121)
+#define __NR_setfsuid (__X32_SYSCALL_BIT + 122)
+#define __NR_setfsgid (__X32_SYSCALL_BIT + 123)
+#define __NR_getsid (__X32_SYSCALL_BIT + 124)
+#define __NR_capget (__X32_SYSCALL_BIT + 125)
+#define __NR_capset (__X32_SYSCALL_BIT + 126)
+#define __NR_rt_sigsuspend (__X32_SYSCALL_BIT + 130)
+#define __NR_utime (__X32_SYSCALL_BIT + 132)
+#define __NR_mknod (__X32_SYSCALL_BIT + 133)
+#define __NR_personality (__X32_SYSCALL_BIT + 135)
+#define __NR_ustat (__X32_SYSCALL_BIT + 136)
+#define __NR_statfs (__X32_SYSCALL_BIT + 137)
+#define __NR_fstatfs (__X32_SYSCALL_BIT + 138)
+#define __NR_sysfs (__X32_SYSCALL_BIT + 139)
+#define __NR_getpriority (__X32_SYSCALL_BIT + 140)
+#define __NR_setpriority (__X32_SYSCALL_BIT + 141)
+#define __NR_sched_setparam (__X32_SYSCALL_BIT + 142)
+#define __NR_sched_getparam (__X32_SYSCALL_BIT + 143)
+#define __NR_sched_setscheduler (__X32_SYSCALL_BIT + 144)
+#define __NR_sched_getscheduler (__X32_SYSCALL_BIT + 145)
+#define __NR_sched_get_priority_max (__X32_SYSCALL_BIT + 146)
+#define __NR_sched_get_priority_min (__X32_SYSCALL_BIT + 147)
+#define __NR_sched_rr_get_interval (__X32_SYSCALL_BIT + 148)
+#define __NR_mlock (__X32_SYSCALL_BIT + 149)
+#define __NR_munlock (__X32_SYSCALL_BIT + 150)
+#define __NR_mlockall (__X32_SYSCALL_BIT + 151)
+#define __NR_munlockall (__X32_SYSCALL_BIT + 152)
+#define __NR_vhangup (__X32_SYSCALL_BIT + 153)
+#define __NR_modify_ldt (__X32_SYSCALL_BIT + 154)
+#define __NR_pivot_root (__X32_SYSCALL_BIT + 155)
+#define __NR_prctl (__X32_SYSCALL_BIT + 157)
+#define __NR_arch_prctl (__X32_SYSCALL_BIT + 158)
+#define __NR_adjtimex (__X32_SYSCALL_BIT + 159)
+#define __NR_setrlimit (__X32_SYSCALL_BIT + 160)
+#define __NR_chroot (__X32_SYSCALL_BIT + 161)
+#define __NR_sync (__X32_SYSCALL_BIT + 162)
+#define __NR_acct (__X32_SYSCALL_BIT + 163)
+#define __NR_settimeofday (__X32_SYSCALL_BIT + 164)
+#define __NR_mount (__X32_SYSCALL_BIT + 165)
+#define __NR_umount2 (__X32_SYSCALL_BIT + 166)
+#define __NR_swapon (__X32_SYSCALL_BIT + 167)
+#define __NR_swapoff (__X32_SYSCALL_BIT + 168)
+#define __NR_reboot (__X32_SYSCALL_BIT + 169)
+#define __NR_sethostname (__X32_SYSCALL_BIT + 170)
+#define __NR_setdomainname (__X32_SYSCALL_BIT + 171)
+#define __NR_iopl (__X32_SYSCALL_BIT + 172)
+#define __NR_ioperm (__X32_SYSCALL_BIT + 173)
+#define __NR_init_module (__X32_SYSCALL_BIT + 175)
+#define __NR_delete_module (__X32_SYSCALL_BIT + 176)
+#define __NR_quotactl (__X32_SYSCALL_BIT + 179)
+#define __NR_getpmsg (__X32_SYSCALL_BIT + 181)
+#define __NR_putpmsg (__X32_SYSCALL_BIT + 182)
+#define __NR_afs_syscall (__X32_SYSCALL_BIT + 183)
+#define __NR_tuxcall (__X32_SYSCALL_BIT + 184)
+#define __NR_security (__X32_SYSCALL_BIT + 185)
+#define __NR_gettid (__X32_SYSCALL_BIT + 186)
+#define __NR_readahead (__X32_SYSCALL_BIT + 187)
+#define __NR_setxattr (__X32_SYSCALL_BIT + 188)
+#define __NR_lsetxattr (__X32_SYSCALL_BIT + 189)
+#define __NR_fsetxattr (__X32_SYSCALL_BIT + 190)
+#define __NR_getxattr (__X32_SYSCALL_BIT + 191)
+#define __NR_lgetxattr (__X32_SYSCALL_BIT + 192)
+#define __NR_fgetxattr (__X32_SYSCALL_BIT + 193)
+#define __NR_listxattr (__X32_SYSCALL_BIT + 194)
+#define __NR_llistxattr (__X32_SYSCALL_BIT + 195)
+#define __NR_flistxattr (__X32_SYSCALL_BIT + 196)
+#define __NR_removexattr (__X32_SYSCALL_BIT + 197)
+#define __NR_lremovexattr (__X32_SYSCALL_BIT + 198)
+#define __NR_fremovexattr (__X32_SYSCALL_BIT + 199)
+#define __NR_tkill (__X32_SYSCALL_BIT + 200)
+#define __NR_time (__X32_SYSCALL_BIT + 201)
+#define __NR_futex (__X32_SYSCALL_BIT + 202)
+#define __NR_sched_setaffinity (__X32_SYSCALL_BIT + 203)
+#define __NR_sched_getaffinity (__X32_SYSCALL_BIT + 204)
+#define __NR_io_setup (__X32_SYSCALL_BIT + 206)
+#define __NR_io_destroy (__X32_SYSCALL_BIT + 207)
+#define __NR_io_getevents (__X32_SYSCALL_BIT + 208)
+#define __NR_io_submit (__X32_SYSCALL_BIT + 209)
+#define __NR_io_cancel (__X32_SYSCALL_BIT + 210)
+#define __NR_lookup_dcookie (__X32_SYSCALL_BIT + 212)
+#define __NR_epoll_create (__X32_SYSCALL_BIT + 213)
+#define __NR_remap_file_pages (__X32_SYSCALL_BIT + 216)
+#define __NR_getdents64 (__X32_SYSCALL_BIT + 217)
+#define __NR_set_tid_address (__X32_SYSCALL_BIT + 218)
+#define __NR_restart_syscall (__X32_SYSCALL_BIT + 219)
+#define __NR_semtimedop (__X32_SYSCALL_BIT + 220)
+#define __NR_fadvise64 (__X32_SYSCALL_BIT + 221)
+#define __NR_timer_settime (__X32_SYSCALL_BIT + 223)
+#define __NR_timer_gettime (__X32_SYSCALL_BIT + 224)
+#define __NR_timer_getoverrun (__X32_SYSCALL_BIT + 225)
+#define __NR_timer_delete (__X32_SYSCALL_BIT + 226)
+#define __NR_clock_settime (__X32_SYSCALL_BIT + 227)
+#define __NR_clock_gettime (__X32_SYSCALL_BIT + 228)
+#define __NR_clock_getres (__X32_SYSCALL_BIT + 229)
+#define __NR_clock_nanosleep (__X32_SYSCALL_BIT + 230)
+#define __NR_exit_group (__X32_SYSCALL_BIT + 231)
+#define __NR_epoll_wait (__X32_SYSCALL_BIT + 232)
+#define __NR_epoll_ctl (__X32_SYSCALL_BIT + 233)
+#define __NR_tgkill (__X32_SYSCALL_BIT + 234)
+#define __NR_utimes (__X32_SYSCALL_BIT + 235)
+#define __NR_mbind (__X32_SYSCALL_BIT + 237)
+#define __NR_set_mempolicy (__X32_SYSCALL_BIT + 238)
+#define __NR_get_mempolicy (__X32_SYSCALL_BIT + 239)
+#define __NR_mq_open (__X32_SYSCALL_BIT + 240)
+#define __NR_mq_unlink (__X32_SYSCALL_BIT + 241)
+#define __NR_mq_timedsend (__X32_SYSCALL_BIT + 242)
+#define __NR_mq_timedreceive (__X32_SYSCALL_BIT + 243)
+#define __NR_mq_getsetattr (__X32_SYSCALL_BIT + 245)
+#define __NR_add_key (__X32_SYSCALL_BIT + 248)
+#define __NR_request_key (__X32_SYSCALL_BIT + 249)
+#define __NR_keyctl (__X32_SYSCALL_BIT + 250)
+#define __NR_ioprio_set (__X32_SYSCALL_BIT + 251)
+#define __NR_ioprio_get (__X32_SYSCALL_BIT + 252)
+#define __NR_inotify_init (__X32_SYSCALL_BIT + 253)
+#define __NR_inotify_add_watch (__X32_SYSCALL_BIT + 254)
+#define __NR_inotify_rm_watch (__X32_SYSCALL_BIT + 255)
+#define __NR_migrate_pages (__X32_SYSCALL_BIT + 256)
+#define __NR_openat (__X32_SYSCALL_BIT + 257)
+#define __NR_mkdirat (__X32_SYSCALL_BIT + 258)
+#define __NR_mknodat (__X32_SYSCALL_BIT + 259)
+#define __NR_fchownat (__X32_SYSCALL_BIT + 260)
+#define __NR_futimesat (__X32_SYSCALL_BIT + 261)
+#define __NR_newfstatat (__X32_SYSCALL_BIT + 262)
+#define __NR_unlinkat (__X32_SYSCALL_BIT + 263)
+#define __NR_renameat (__X32_SYSCALL_BIT + 264)
+#define __NR_linkat (__X32_SYSCALL_BIT + 265)
+#define __NR_symlinkat (__X32_SYSCALL_BIT + 266)
+#define __NR_readlinkat (__X32_SYSCALL_BIT + 267)
+#define __NR_fchmodat (__X32_SYSCALL_BIT + 268)
+#define __NR_faccessat (__X32_SYSCALL_BIT + 269)
+#define __NR_pselect6 (__X32_SYSCALL_BIT + 270)
+#define __NR_ppoll (__X32_SYSCALL_BIT + 271)
+#define __NR_unshare (__X32_SYSCALL_BIT + 272)
+#define __NR_splice (__X32_SYSCALL_BIT + 275)
+#define __NR_tee (__X32_SYSCALL_BIT + 276)
+#define __NR_sync_file_range (__X32_SYSCALL_BIT + 277)
+#define __NR_utimensat (__X32_SYSCALL_BIT + 280)
+#define __NR_epoll_pwait (__X32_SYSCALL_BIT + 281)
+#define __NR_signalfd (__X32_SYSCALL_BIT + 282)
+#define __NR_timerfd_create (__X32_SYSCALL_BIT + 283)
+#define __NR_eventfd (__X32_SYSCALL_BIT + 284)
+#define __NR_fallocate (__X32_SYSCALL_BIT + 285)
+#define __NR_timerfd_settime (__X32_SYSCALL_BIT + 286)
+#define __NR_timerfd_gettime (__X32_SYSCALL_BIT + 287)
+#define __NR_accept4 (__X32_SYSCALL_BIT + 288)
+#define __NR_signalfd4 (__X32_SYSCALL_BIT + 289)
+#define __NR_eventfd2 (__X32_SYSCALL_BIT + 290)
+#define __NR_epoll_create1 (__X32_SYSCALL_BIT + 291)
+#define __NR_dup3 (__X32_SYSCALL_BIT + 292)
+#define __NR_pipe2 (__X32_SYSCALL_BIT + 293)
+#define __NR_inotify_init1 (__X32_SYSCALL_BIT + 294)
+#define __NR_perf_event_open (__X32_SYSCALL_BIT + 298)
+#define __NR_fanotify_init (__X32_SYSCALL_BIT + 300)
+#define __NR_fanotify_mark (__X32_SYSCALL_BIT + 301)
+#define __NR_prlimit64 (__X32_SYSCALL_BIT + 302)
+#define __NR_name_to_handle_at (__X32_SYSCALL_BIT + 303)
+#define __NR_open_by_handle_at (__X32_SYSCALL_BIT + 304)
+#define __NR_clock_adjtime (__X32_SYSCALL_BIT + 305)
+#define __NR_syncfs (__X32_SYSCALL_BIT + 306)
+#define __NR_setns (__X32_SYSCALL_BIT + 308)
+#define __NR_getcpu (__X32_SYSCALL_BIT + 309)
+#define __NR_kcmp (__X32_SYSCALL_BIT + 312)
+#define __NR_finit_module (__X32_SYSCALL_BIT + 313)
+#define __NR_rt_sigaction (__X32_SYSCALL_BIT + 512)
+#define __NR_rt_sigreturn (__X32_SYSCALL_BIT + 513)
+#define __NR_ioctl (__X32_SYSCALL_BIT + 514)
+#define __NR_readv (__X32_SYSCALL_BIT + 515)
+#define __NR_writev (__X32_SYSCALL_BIT + 516)
+#define __NR_recvfrom (__X32_SYSCALL_BIT + 517)
+#define __NR_sendmsg (__X32_SYSCALL_BIT + 518)
+#define __NR_recvmsg (__X32_SYSCALL_BIT + 519)
+#define __NR_execve (__X32_SYSCALL_BIT + 520)
+#define __NR_ptrace (__X32_SYSCALL_BIT + 521)
+#define __NR_rt_sigpending (__X32_SYSCALL_BIT + 522)
+#define __NR_rt_sigtimedwait (__X32_SYSCALL_BIT + 523)
+#define __NR_rt_sigqueueinfo (__X32_SYSCALL_BIT + 524)
+#define __NR_sigaltstack (__X32_SYSCALL_BIT + 525)
+#define __NR_timer_create (__X32_SYSCALL_BIT + 526)
+#define __NR_mq_notify (__X32_SYSCALL_BIT + 527)
+#define __NR_kexec_load (__X32_SYSCALL_BIT + 528)
+#define __NR_waitid (__X32_SYSCALL_BIT + 529)
+#define __NR_set_robust_list (__X32_SYSCALL_BIT + 530)
+#define __NR_get_robust_list (__X32_SYSCALL_BIT + 531)
+#define __NR_vmsplice (__X32_SYSCALL_BIT + 532)
+#define __NR_move_pages (__X32_SYSCALL_BIT + 533)
+#define __NR_preadv (__X32_SYSCALL_BIT + 534)
+#define __NR_pwritev (__X32_SYSCALL_BIT + 535)
+#define __NR_rt_tgsigqueueinfo (__X32_SYSCALL_BIT + 536)
+#define __NR_recvmmsg (__X32_SYSCALL_BIT + 537)
+#define __NR_sendmmsg (__X32_SYSCALL_BIT + 538)
+#define __NR_process_vm_readv (__X32_SYSCALL_BIT + 539)
+#define __NR_process_vm_writev (__X32_SYSCALL_BIT + 540)
+#define __NR_setsockopt (__X32_SYSCALL_BIT + 541)
+#define __NR_getsockopt (__X32_SYSCALL_BIT + 542)
+
+#undef __NR_fstatat
+#undef __NR_pread
+#undef __NR_pwrite
+#undef __NR_getdents
+#define __NR_fstatat __NR_newfstatat
+#define __NR_pread __NR_pread64
+#define __NR_pwrite __NR_pwrite64
+#define __NR_getdents __NR_getdents64
+#define __NR_fadvise __NR_fadvise64
+
+
+
+/* Repeat with SYS_ prefix */
+
+
+
+#define SYS_read __NR_read
+#define SYS_write __NR_write
+#define SYS_open __NR_open
+#define SYS_close __NR_close
+#define SYS_stat __NR_stat
+#define SYS_fstat __NR_fstat
+#define SYS_lstat __NR_lstat
+#define SYS_poll __NR_poll
+#define SYS_lseek __NR_lseek
+#define SYS_mmap __NR_mmap
+#define SYS_mprotect __NR_mprotect
+#define SYS_munmap __NR_munmap
+#define SYS_brk __NR_brk
+#define SYS_rt_sigprocmask __NR_rt_sigprocmask
+#define SYS_pread64 __NR_pread64
+#define SYS_pwrite64 __NR_pwrite64
+#define SYS_access __NR_access
+#define SYS_pipe __NR_pipe
+#define SYS_select __NR_select
+#define SYS_sched_yield __NR_sched_yield
+#define SYS_mremap __NR_mremap
+#define SYS_msync __NR_msync
+#define SYS_mincore __NR_mincore
+#define SYS_madvise __NR_madvise
+#define SYS_shmget __NR_shmget
+#define SYS_shmat __NR_shmat
+#define SYS_shmctl __NR_shmctl
+#define SYS_dup __NR_dup
+#define SYS_dup2 __NR_dup2
+#define SYS_pause __NR_pause
+#define SYS_nanosleep __NR_nanosleep
+#define SYS_getitimer __NR_getitimer
+#define SYS_alarm __NR_alarm
+#define SYS_setitimer __NR_setitimer
+#define SYS_getpid __NR_getpid
+#define SYS_sendfile __NR_sendfile
+#define SYS_socket __NR_socket
+#define SYS_connect __NR_connect
+#define SYS_accept __NR_accept
+#define SYS_sendto __NR_sendto
+#define SYS_shutdown __NR_shutdown
+#define SYS_bind __NR_bind
+#define SYS_listen __NR_listen
+#define SYS_getsockname __NR_getsockname
+#define SYS_getpeername __NR_getpeername
+#define SYS_socketpair __NR_socketpair
+#define SYS_clone __NR_clone
+#define SYS_fork __NR_fork
+#define SYS_vfork __NR_vfork
+#define SYS_exit __NR_exit
+#define SYS_wait4 __NR_wait4
+#define SYS_kill __NR_kill
+#define SYS_uname __NR_uname
+#define SYS_semget __NR_semget
+#define SYS_semop __NR_semop
+#define SYS_semctl __NR_semctl
+#define SYS_shmdt __NR_shmdt
+#define SYS_msgget __NR_msgget
+#define SYS_msgsnd __NR_msgsnd
+#define SYS_msgrcv __NR_msgrcv
+#define SYS_msgctl __NR_msgctl
+#define SYS_fcntl __NR_fcntl
+#define SYS_flock __NR_flock
+#define SYS_fsync __NR_fsync
+#define SYS_fdatasync __NR_fdatasync
+#define SYS_truncate __NR_truncate
+#define SYS_ftruncate __NR_ftruncate
+#define SYS_getdents __NR_getdents
+#define SYS_getcwd __NR_getcwd
+#define SYS_chdir __NR_chdir
+#define SYS_fchdir __NR_fchdir
+#define SYS_rename __NR_rename
+#define SYS_mkdir __NR_mkdir
+#define SYS_rmdir __NR_rmdir
+#define SYS_creat __NR_creat
+#define SYS_link __NR_link
+#define SYS_unlink __NR_unlink
+#define SYS_symlink __NR_symlink
+#define SYS_readlink __NR_readlink
+#define SYS_chmod __NR_chmod
+#define SYS_fchmod __NR_fchmod
+#define SYS_chown __NR_chown
+#define SYS_fchown __NR_fchown
+#define SYS_lchown __NR_lchown
+#define SYS_umask __NR_umask
+#define SYS_gettimeofday __NR_gettimeofday
+#define SYS_getrlimit __NR_getrlimit
+#define SYS_getrusage __NR_getrusage
+#define SYS_sysinfo __NR_sysinfo
+#define SYS_times __NR_times
+#define SYS_getuid __NR_getuid
+#define SYS_syslog __NR_syslog
+#define SYS_getgid __NR_getgid
+#define SYS_setuid __NR_setuid
+#define SYS_setgid __NR_setgid
+#define SYS_geteuid __NR_geteuid
+#define SYS_getegid __NR_getegid
+#define SYS_setpgid __NR_setpgid
+#define SYS_getppid __NR_getppid
+#define SYS_getpgrp __NR_getpgrp
+#define SYS_setsid __NR_setsid
+#define SYS_setreuid __NR_setreuid
+#define SYS_setregid __NR_setregid
+#define SYS_getgroups __NR_getgroups
+#define SYS_setgroups __NR_setgroups
+#define SYS_setresuid __NR_setresuid
+#define SYS_getresuid __NR_getresuid
+#define SYS_setresgid __NR_setresgid
+#define SYS_getresgid __NR_getresgid
+#define SYS_getpgid __NR_getpgid
+#define SYS_setfsuid __NR_setfsuid
+#define SYS_setfsgid __NR_setfsgid
+#define SYS_getsid __NR_getsid
+#define SYS_capget __NR_capget
+#define SYS_capset __NR_capset
+#define SYS_rt_sigsuspend __NR_rt_sigsuspend
+#define SYS_utime __NR_utime
+#define SYS_mknod __NR_mknod
+#define SYS_personality __NR_personality
+#define SYS_ustat __NR_ustat
+#define SYS_statfs __NR_statfs
+#define SYS_fstatfs __NR_fstatfs
+#define SYS_sysfs __NR_sysfs
+#define SYS_getpriority __NR_getpriority
+#define SYS_setpriority __NR_setpriority
+#define SYS_sched_setparam __NR_sched_setparam
+#define SYS_sched_getparam __NR_sched_getparam
+#define SYS_sched_setscheduler __NR_sched_setscheduler
+#define SYS_sched_getscheduler __NR_sched_getscheduler
+#define SYS_sched_get_priority_max __NR_sched_get_priority_max
+#define SYS_sched_get_priority_min __NR_sched_get_priority_min
+#define SYS_sched_rr_get_interval __NR_sched_rr_get_interval
+#define SYS_mlock __NR_mlock
+#define SYS_munlock __NR_munlock
+#define SYS_mlockall __NR_mlockall
+#define SYS_munlockall __NR_munlockall
+#define SYS_vhangup __NR_vhangup
+#define SYS_modify_ldt __NR_modify_ldt
+#define SYS_pivot_root __NR_pivot_root
+#define SYS_prctl __NR_prctl
+#define SYS_arch_prctl __NR_arch_prctl
+#define SYS_adjtimex __NR_adjtimex
+#define SYS_setrlimit __NR_setrlimit
+#define SYS_chroot __NR_chroot
+#define SYS_sync __NR_sync
+#define SYS_acct __NR_acct
+#define SYS_settimeofday __NR_settimeofday
+#define SYS_mount __NR_mount
+#define SYS_umount2 __NR_umount2
+#define SYS_swapon __NR_swapon
+#define SYS_swapoff __NR_swapoff
+#define SYS_reboot __NR_reboot
+#define SYS_sethostname __NR_sethostname
+#define SYS_setdomainname __NR_setdomainname
+#define SYS_iopl __NR_iopl
+#define SYS_ioperm __NR_ioperm
+#define SYS_init_module __NR_init_module
+#define SYS_delete_module __NR_delete_module
+#define SYS_quotactl __NR_quotactl
+#define SYS_getpmsg __NR_getpmsg
+#define SYS_putpmsg __NR_putpmsg
+#define SYS_afs_syscall __NR_afs_syscall
+#define SYS_tuxcall __NR_tuxcall
+#define SYS_security __NR_security
+#define SYS_gettid __NR_gettid
+#define SYS_readahead __NR_readahead
+#define SYS_setxattr __NR_setxattr
+#define SYS_lsetxattr __NR_lsetxattr
+#define SYS_fsetxattr __NR_fsetxattr
+#define SYS_getxattr __NR_getxattr
+#define SYS_lgetxattr __NR_lgetxattr
+#define SYS_fgetxattr __NR_fgetxattr
+#define SYS_listxattr __NR_listxattr
+#define SYS_llistxattr __NR_llistxattr
+#define SYS_flistxattr __NR_flistxattr
+#define SYS_removexattr __NR_removexattr
+#define SYS_lremovexattr __NR_lremovexattr
+#define SYS_fremovexattr __NR_fremovexattr
+#define SYS_tkill __NR_tkill
+#define SYS_time __NR_time
+#define SYS_futex __NR_futex
+#define SYS_sched_setaffinity __NR_sched_setaffinity
+#define SYS_sched_getaffinity __NR_sched_getaffinity
+#define SYS_io_setup __NR_io_setup
+#define SYS_io_destroy __NR_io_destroy
+#define SYS_io_getevents __NR_io_getevents
+#define SYS_io_submit __NR_io_submit
+#define SYS_io_cancel __NR_io_cancel
+#define SYS_lookup_dcookie __NR_lookup_dcookie
+#define SYS_epoll_create __NR_epoll_create
+#define SYS_remap_file_pages __NR_remap_file_pages
+#define SYS_getdents64 __NR_getdents64
+#define SYS_set_tid_address __NR_set_tid_address
+#define SYS_restart_syscall __NR_restart_syscall
+#define SYS_semtimedop __NR_semtimedop
+#define SYS_fadvise64 __NR_fadvise64
+#define SYS_timer_settime __NR_timer_settime
+#define SYS_timer_gettime __NR_timer_gettime
+#define SYS_timer_getoverrun __NR_timer_getoverrun
+#define SYS_timer_delete __NR_timer_delete
+#define SYS_clock_settime __NR_clock_settime
+#define SYS_clock_gettime __NR_clock_gettime
+#define SYS_clock_getres __NR_clock_getres
+#define SYS_clock_nanosleep __NR_clock_nanosleep
+#define SYS_exit_group __NR_exit_group
+#define SYS_epoll_wait __NR_epoll_wait
+#define SYS_epoll_ctl __NR_epoll_ctl
+#define SYS_tgkill __NR_tgkill
+#define SYS_utimes __NR_utimes
+#define SYS_mbind __NR_mbind
+#define SYS_set_mempolicy __NR_set_mempolicy
+#define SYS_get_mempolicy __NR_get_mempolicy
+#define SYS_mq_open __NR_mq_open
+#define SYS_mq_unlink __NR_mq_unlink
+#define SYS_mq_timedsend __NR_mq_timedsend
+#define SYS_mq_timedreceive __NR_mq_timedreceive
+#define SYS_mq_getsetattr __NR_mq_getsetattr
+#define SYS_add_key __NR_add_key
+#define SYS_request_key __NR_request_key
+#define SYS_keyctl __NR_keyctl
+#define SYS_ioprio_set __NR_ioprio_set
+#define SYS_ioprio_get __NR_ioprio_get
+#define SYS_inotify_init __NR_inotify_init
+#define SYS_inotify_add_watch __NR_inotify_add_watch
+#define SYS_inotify_rm_watch __NR_inotify_rm_watch
+#define SYS_migrate_pages __NR_migrate_pages
+#define SYS_openat __NR_openat
+#define SYS_mkdirat __NR_mkdirat
+#define SYS_mknodat __NR_mknodat
+#define SYS_fchownat __NR_fchownat
+#define SYS_futimesat __NR_futimesat
+#define SYS_newfstatat __NR_newfstatat
+#define SYS_unlinkat __NR_unlinkat
+#define SYS_renameat __NR_renameat
+#define SYS_linkat __NR_linkat
+#define SYS_symlinkat __NR_symlinkat
+#define SYS_readlinkat __NR_readlinkat
+#define SYS_fchmodat __NR_fchmodat
+#define SYS_faccessat __NR_faccessat
+#define SYS_pselect6 __NR_pselect6
+#define SYS_ppoll __NR_ppoll
+#define SYS_unshare __NR_unshare
+#define SYS_splice __NR_splice
+#define SYS_tee __NR_tee
+#define SYS_sync_file_range __NR_sync_file_range
+#define SYS_utimensat __NR_utimensat
+#define SYS_epoll_pwait __NR_epoll_pwait
+#define SYS_signalfd __NR_signalfd
+#define SYS_timerfd_create __NR_timerfd_create
+#define SYS_eventfd __NR_eventfd
+#define SYS_fallocate __NR_fallocate
+#define SYS_timerfd_settime __NR_timerfd_settime
+#define SYS_timerfd_gettime __NR_timerfd_gettime
+#define SYS_accept4 __NR_accept4
+#define SYS_signalfd4 __NR_signalfd4
+#define SYS_eventfd2 __NR_eventfd2
+#define SYS_epoll_create1 __NR_epoll_create1
+#define SYS_dup3 __NR_dup3
+#define SYS_pipe2 __NR_pipe2
+#define SYS_inotify_init1 __NR_inotify_init1
+#define SYS_perf_event_open __NR_perf_event_open
+#define SYS_fanotify_init __NR_fanotify_init
+#define SYS_fanotify_mark __NR_fanotify_mark
+#define SYS_prlimit64 __NR_prlimit64
+#define SYS_name_to_handle_at __NR_name_to_handle_at
+#define SYS_open_by_handle_at __NR_open_by_handle_at
+#define SYS_clock_adjtime __NR_clock_adjtime
+#define SYS_syncfs __NR_syncfs
+#define SYS_setns __NR_setns
+#define SYS_getcpu __NR_getcpu
+#define SYS_kcmp __NR_kcmp
+#define SYS_finit_module __NR_finit_module
+#define SYS_rt_sigaction __NR_rt_sigaction
+#define SYS_rt_sigreturn __NR_rt_sigreturn
+#define SYS_ioctl __NR_ioctl
+#define SYS_readv __NR_readv
+#define SYS_writev __NR_writev
+#define SYS_recvfrom __NR_recvfrom
+#define SYS_sendmsg __NR_sendmsg
+#define SYS_recvmsg __NR_recvmsg
+#define SYS_execve __NR_execve
+#define SYS_ptrace __NR_ptrace
+#define SYS_rt_sigpending __NR_rt_sigpending
+#define SYS_rt_sigtimedwait __NR_rt_sigtimedwait
+#define SYS_rt_sigqueueinfo __NR_rt_sigqueueinfo
+#define SYS_sigaltstack __NR_sigaltstack
+#define SYS_timer_create __NR_timer_create
+#define SYS_mq_notify __NR_mq_notify
+#define SYS_kexec_load __NR_kexec_load
+#define SYS_waitid __NR_waitid
+#define SYS_set_robust_list __NR_set_robust_list
+#define SYS_get_robust_list __NR_get_robust_list
+#define SYS_vmsplice __NR_vmsplice
+#define SYS_move_pages __NR_move_pages
+#define SYS_preadv __NR_preadv
+#define SYS_pwritev __NR_pwritev
+#define SYS_rt_tgsigqueueinfo __NR_rt_tgsigqueueinfo
+#define SYS_recvmmsg __NR_recvmmsg
+#define SYS_sendmmsg __NR_sendmmsg
+#define SYS_process_vm_readv __NR_process_vm_readv
+#define SYS_process_vm_writev __NR_process_vm_writev
+#define SYS_setsockopt __NR_setsockopt
+#define SYS_getsockopt __NR_getsockopt
+
+#undef SYS_fstatat
+#undef SYS_pread
+#undef SYS_pwrite
+#undef SYS_getdents
+#define SYS_fstatat SYS_newfstatat
+#define SYS_pread SYS_pread64
+#define SYS_pwrite SYS_pwrite64
+#define SYS_getdents SYS_getdents64
+#define SYS_fadvise SYS_fadvise64
diff --git a/arch/x32/bits/termios.h b/arch/x32/bits/termios.h
new file mode 100644
index 0000000..61c888f
--- /dev/null
+++ b/arch/x32/bits/termios.h
@@ -0,0 +1,160 @@
+struct termios
+{
+	tcflag_t c_iflag;
+	tcflag_t c_oflag;
+	tcflag_t c_cflag;
+	tcflag_t c_lflag;
+	cc_t c_line;
+	cc_t c_cc[NCCS];
+	speed_t __c_ispeed;
+	speed_t __c_ospeed;
+};
+
+#define VINTR     0
+#define VQUIT     1
+#define VERASE    2
+#define VKILL     3
+#define VEOF      4
+#define VTIME     5
+#define VMIN      6
+#define VSWTC     7
+#define VSTART    8
+#define VSTOP     9
+#define VSUSP    10
+#define VEOL     11
+#define VREPRINT 12
+#define VDISCARD 13
+#define VWERASE  14
+#define VLNEXT   15
+#define VEOL2    16
+
+#define IGNBRK  0000001
+#define BRKINT  0000002
+#define IGNPAR  0000004
+#define PARMRK  0000010
+#define INPCK   0000020
+#define ISTRIP  0000040
+#define INLCR   0000100
+#define IGNCR   0000200
+#define ICRNL   0000400
+#define IUCLC   0001000
+#define IXON    0002000
+#define IXANY   0004000
+#define IXOFF   0010000
+#define IMAXBEL 0020000
+
+#define OPOST  0000001
+#define OLCUC  0000002
+#define ONLCR  0000004
+#define OCRNL  0000010
+#define ONOCR  0000020
+#define ONLRET 0000040
+#define OFILL  0000100
+#define OFDEL  0000200
+#define NLDLY  0000400
+#define NL0    0000000
+#define NL1    0000400
+#define CRDLY  0003000
+#define CR0    0000000
+#define CR1    0001000
+#define CR2    0002000
+#define CR3    0003000
+#define TABDLY 0014000
+#define TAB0   0000000
+#define TAB1   0004000
+#define TAB2   0010000
+#define TAB3   0014000
+#define BSDLY  0020000
+#define BS0    0000000
+#define BS1    0020000
+#define FFDLY  0100000
+#define FF0    0000000
+#define FF1    0100000
+
+#define VTDLY  0040000
+#define VT0    0000000
+#define VT1    0040000
+
+/* ?? */
+#define XTABS  0014000
+
+#define B0       0000000
+#define B50      0000001
+#define B75      0000002
+#define B110     0000003
+#define B134     0000004
+#define B150     0000005
+#define B200     0000006
+#define B300     0000007
+#define B600     0000010
+#define B1200    0000011
+#define B1800    0000012
+#define B2400    0000013
+#define B4800    0000014
+#define B9600    0000015
+#define B19200   0000016
+#define B38400   0000017
+
+#define B57600   0010001
+#define B115200  0010002
+#define B230400  0010003
+#define B460800  0010004
+#define B500000  0010005
+#define B576000  0010006
+#define B921600  0010007
+#define B1000000 0010010
+#define B1152000 0010011
+#define B1500000 0010012
+#define B2000000 0010013
+#define B2500000 0010014
+#define B3000000 0010015
+#define B3500000 0010016
+#define B4000000 0010017
+
+#define CBAUD    0010017
+
+#define CSIZE  0000060
+#define CS5    0000000
+#define CS6    0000020
+#define CS7    0000040
+#define CS8    0000060
+#define CSTOPB 0000100
+#define CREAD  0000200
+#define PARENB 0000400
+#define PARODD 0001000
+#define HUPCL  0002000
+#define CLOCAL 0004000
+
+#define CRTSCTS  020000000000
+
+#define ISIG   0000001
+#define ICANON 0000002
+#define ECHO   0000010
+#define ECHOE  0000020
+#define ECHOK  0000040
+#define ECHONL 0000100
+#define NOFLSH 0000200
+#define TOSTOP 0000400
+#define IEXTEN 0100000
+
+/* Extensions? */
+#define CBAUDEX 0010000
+#define ECHOCTL 0001000
+#define ECHOPRT 0002000
+#define ECHOKE 0004000
+#define FLUSHO 0010000
+#define PENDIN 0040000
+#define EXTPROC 0200000
+
+#define TCOOFF 0
+#define TCOON  1
+#define TCIOFF 2
+#define TCION  3
+
+#define TCIFLUSH  0
+#define TCOFLUSH  1
+#define TCIOFLUSH 2
+
+#define TCSANOW   0
+#define TCSADRAIN 1
+#define TCSAFLUSH 2
diff --git a/arch/x32/bits/user.h b/arch/x32/bits/user.h
new file mode 100644
index 0000000..8b42632
--- /dev/null
+++ b/arch/x32/bits/user.h
@@ -0,0 +1,44 @@
+#undef __WORDSIZE
+#define __WORDSIZE 64
+
+typedef struct user_fpregs_struct
+{
+	uint16_t cwd, swd, ftw, fop;
+	uint64_t rip, rdp;
+	uint32_t mxcsr, mxcs_mask;
+	uint32_t st_space[32], xmm_space[64], padding[24];
+} elf_fpregset_t;
+
+struct user_regs_struct
+{
+	unsigned long r15, r14, r13, r12, rbp, rbx, r11, r10, r9, r8;
+	unsigned long rax, rcx, rdx, rsi, rdi, orig_rax, rip;
+	unsigned long cs, eflags, rsp, ss, fs_base, gs_base, ds, es, fs, gs;
+};
+#define ELF_NGREG 27
+typedef unsigned long long elf_greg_t, elf_gregset_t[ELF_NGREG];
+
+struct user
+{
+	struct user_regs_struct		regs;
+	int				u_fpvalid;
+	struct user_fpregs_struct	i387;
+	unsigned long			u_tsize;
+	unsigned long			u_dsize;
+	unsigned long			u_ssize;
+	unsigned long			start_code;
+	unsigned long			start_stack;
+	long				signal;
+	int				reserved;
+	struct user_regs_struct		*u_ar0;
+	struct user_fpregs_struct	*u_fpstate;
+	unsigned long			magic;
+	char				u_comm[32];
+	unsigned long			u_debugreg[8];
+};
+
+#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/x32/crt_arch.h b/arch/x32/crt_arch.h
new file mode 100644
index 0000000..db69295
--- /dev/null
+++ b/arch/x32/crt_arch.h
@@ -0,0 +1,9 @@
+__asm__("\
+.text \n\
+.global _start \n\
+_start: \n\
+	xor %rbp,%rbp \n\
+	mov %rsp,%rdi \n\
+	andq $-16,%rsp \n\
+	call __cstart \n\
+");
diff --git a/arch/x32/pthread_arch.h b/arch/x32/pthread_arch.h
new file mode 100644
index 0000000..f671c74
--- /dev/null
+++ b/arch/x32/pthread_arch.h
@@ -0,0 +1,10 @@
+static inline struct pthread *__pthread_self()
+{
+	struct pthread *self;
+	__asm__ __volatile__ ("movl %%fs:0,%0" : "=r" (self) );
+	return self;
+}
+
+#define TP_ADJ(p) (p)
+
+#define CANCEL_REG_IP 16
diff --git a/arch/x32/reloc.h b/arch/x32/reloc.h
new file mode 100644
index 0000000..28cf7cc
--- /dev/null
+++ b/arch/x32/reloc.h
@@ -0,0 +1,46 @@
+#include <stdint.h>
+#include <string.h>
+#include <elf.h>
+
+#define LDSO_ARCH "x86_64"
+
+#define IS_COPY(x) ((x)==R_X86_64_COPY)
+#define IS_PLT(x) ((x)==R_X86_64_JUMP_SLOT)
+
+static inline void do_single_reloc(
+	struct dso *self, unsigned char *base_addr,
+	size_t *reloc_addr, int type, size_t addend,
+	Sym *sym, size_t sym_size,
+	struct symdef def, size_t sym_val)
+{
+	switch(type) {
+	case R_X86_64_GLOB_DAT:
+	case R_X86_64_JUMP_SLOT:
+	case R_X86_64_64:
+		*reloc_addr = sym_val + addend;
+		break;
+	case R_X86_64_32:
+		*(uint32_t *)reloc_addr = sym_val + addend;
+		break;
+	case R_X86_64_PC32:
+		*reloc_addr = sym_val + addend - (size_t)reloc_addr + (size_t)base_addr;
+		break;
+	case R_X86_64_RELATIVE:
+		*reloc_addr = (size_t)base_addr + addend;
+		break;
+	case R_X86_64_COPY:
+		memcpy(reloc_addr, (void *)sym_val, sym_size);
+		break;
+	case R_X86_64_DTPMOD64:
+		*reloc_addr = def.dso ? def.dso->tls_id : self->tls_id;
+		break;
+	case R_X86_64_DTPOFF64:
+		*reloc_addr = def.sym->st_value + addend;
+		break;
+	case R_X86_64_TPOFF64:
+		*reloc_addr = (def.sym
+			? def.sym->st_value - def.dso->tls_offset
+			: 0 - self->tls_offset) + addend;
+		break;
+	}
+}
diff --git a/arch/x32/syscall_arch.h b/arch/x32/syscall_arch.h
new file mode 100644
index 0000000..1da6497
--- /dev/null
+++ b/arch/x32/syscall_arch.h
@@ -0,0 +1,65 @@
+#define __SYSCALL_LL_E(x) (x)
+#define __SYSCALL_LL_O(x) (x)
+
+static __inline long __syscall0(long long n)
+{
+	unsigned long ret;
+	__asm__ __volatile__ ("syscall" : "=a"(ret) : "a"(n) : "rcx", "r11", "memory");
+	return ret;
+}
+
+static __inline long __syscall1(long long n, long long a1)
+{
+	unsigned long ret;
+	__asm__ __volatile__ ("syscall" : "=a"(ret) : "a"(n), "D"(a1) : "rcx", "r11", "memory");
+	return ret;
+}
+
+static __inline long __syscall2(long long n, long long a1, long long a2)
+{
+	unsigned long ret;
+	__asm__ __volatile__ ("syscall" : "=a"(ret) : "a"(n), "D"(a1), "S"(a2)
+						  : "rcx", "r11", "memory");
+	return ret;
+}
+
+static __inline long __syscall3(long long n, long long a1, long long a2, long long a3)
+{
+	unsigned long ret;
+	__asm__ __volatile__ ("syscall" : "=a"(ret) : "a"(n), "D"(a1), "S"(a2),
+						  "d"(a3) : "rcx", "r11", "memory");
+	return ret;
+}
+
+static __inline long __syscall4(long long n, long long a1, long long a2, long long a3,
+                                     long long a4)
+{
+	unsigned long ret;
+	register long long r10 __asm__("r10") = a4;
+	__asm__ __volatile__ ("syscall" : "=a"(ret) : "a"(n), "D"(a1), "S"(a2),
+						  "d"(a3), "r"(r10): "rcx", "r11", "memory");
+	return ret;
+}
+
+static __inline long __syscall5(long long n, long long a1, long long a2, long long a3,
+                                     long long a4, long long a5)
+{
+	unsigned long ret;
+	register long long r10 __asm__("r10") = a4;
+	register long long r8 __asm__("r8") = a5;
+	__asm__ __volatile__ ("syscall" : "=a"(ret) : "a"(n), "D"(a1), "S"(a2),
+						  "d"(a3), "r"(r10), "r"(r8) : "rcx", "r11", "memory");
+	return ret;
+}
+
+static __inline long __syscall6(long long n, long long a1, long long a2, long long a3,
+                                     long long a4, long long a5, long long a6)
+{
+	unsigned long ret;
+	register long long r10 __asm__("r10") = a4;
+	register long long r8 __asm__("r8") = a5;
+	register long long r9 __asm__("r9") = a6;
+	__asm__ __volatile__ ("syscall" : "=a"(ret) : "a"(n), "D"(a1), "S"(a2),
+						  "d"(a3), "r"(r10), "r"(r8), "r"(r9) : "rcx", "r11", "memory");
+	return ret;
+}
diff --git a/configure b/configure
index aa3cb42..eae2b67 100755
--- a/configure
+++ b/configure
@@ -225,6 +225,7 @@ case "$target" in
 arm*) ARCH=arm ;;
 i?86*) ARCH=i386 ;;
 x86_64*) ARCH=x86_64 ;;
+x32*) ARCH=x32 ;;
 mips-*|mipsel-*) ARCH=mips ;;
 microblaze-*) ARCH=microblaze ;;
 powerpc-*) ARCH=powerpc ;;
diff --git a/crt/x32/Scrt1.s b/crt/x32/Scrt1.s
new file mode 100644
index 0000000..ba34e95
--- /dev/null
+++ b/crt/x32/Scrt1.s
@@ -0,0 +1,16 @@
+/* Written 2011 Nicholas J. Kain, released as Public Domain */
+.weak _init
+.weak _fini
+.text
+.global _start
+_start:
+	xor %rbp,%rbp   /* rbp:undefined -> mark as zero 0 (ABI) */
+	mov %rdx,%r9    /* 6th arg: ptr to register with atexit() */
+	pop %rsi        /* 2nd arg: argc */
+	mov %rsp,%rdx   /* 3rd arg: argv */
+	andq $-16,%rsp  /* align stack pointer */
+	lea _fini(%rip),%r8           /* 5th arg: fini/dtors function */
+	lea _init(%rip),%rcx          /* 4th arg: init/ctors function */
+	mov main@GOTPCREL(%rip),%rdi  /* 1st arg: application entry ip */
+	call __libc_start_main@PLT    /* musl init will run the program */
+1:	jmp 1b
diff --git a/crt/x32/crt1.s b/crt/x32/crt1.s
new file mode 100644
index 0000000..1c06a65
--- /dev/null
+++ b/crt/x32/crt1.s
@@ -0,0 +1,20 @@
+/* Written 2011 Nicholas J. Kain, released as Public Domain */
+.weak _init
+.weak _fini
+.text
+.global _start
+_start:
+	xor %rbp,%rbp   /* rbp:undefined -> mark as zero 0 (ABI) */
+	mov %rdx,%r9    /* 6th arg: ptr to register with atexit() */
+	pop %rsi        /* 2nd arg: argc.
+			   we pop 2 words from the stack,
+			   so rsi contains argv in the high bits and argc in the low bits*/
+	movl %esi, %esi /* clear the upper bits of the argc argument */
+	mov %rsp,%rdx   /* copy address to first argv member into rdx, the reg for the 3rd arg */
+	subq $4, %rdx
+	andq $-16,%rsp  /* align stack pointer */
+	mov $_fini,%r8  /* 5th arg: fini/dtors function */
+	mov $_init,%rcx /* 4th arg: init/ctors function */
+	mov $main,%rdi  /* 1st arg: application entry ip */
+	call __libc_start_main /* musl init will run the program */
+1:	jmp 1b
diff --git a/crt/x32/crti.s b/crt/x32/crti.s
new file mode 100644
index 0000000..4788968
--- /dev/null
+++ b/crt/x32/crti.s
@@ -0,0 +1,9 @@
+.section .init
+.global _init
+_init:
+	push %rax
+
+.section .fini
+.global _fini
+_fini:
+	push %rax
diff --git a/crt/x32/crtn.s b/crt/x32/crtn.s
new file mode 100644
index 0000000..29198b7
--- /dev/null
+++ b/crt/x32/crtn.s
@@ -0,0 +1,7 @@
+.section .init
+	pop %rax
+	ret
+
+.section .fini
+	pop %rax
+	ret
diff --git a/include/sys/msg.h b/include/sys/msg.h
index 139f22b..7ae70b4 100644
--- a/include/sys/msg.h
+++ b/include/sys/msg.h
@@ -15,8 +15,13 @@ extern "C" {
 
 #include <bits/alltypes.h>
 
+#ifndef __ILP32__ /* x32 */
 typedef unsigned long msgqnum_t;
 typedef unsigned long msglen_t;
+#else
+typedef unsigned long long msgqnum_t;
+typedef unsigned long long msglen_t;
+#endif
 
 #include <bits/msg.h>
 
@@ -40,7 +45,11 @@ int msgsnd (int, const void *, size_t, int);
 
 #if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
 struct msgbuf {
+#ifndef __ILP32__ /* x32 */
 	long mtype;
+#else
+	long long mtype;
+#endif
 	char mtext[1];
 };
 #endif
diff --git a/include/sys/sem.h b/include/sys/sem.h
index e74ea20..eb06956 100644
--- a/include/sys/sem.h
+++ b/include/sys/sem.h
@@ -27,21 +27,27 @@ extern "C" {
 
 #include <endian.h>
 
+#ifdef __ILP32__ /* x32 */
+#define __syscall_long long long
+#else
+#define __syscall_long long
+#endif
+
 struct semid_ds {
 	struct ipc_perm sem_perm;
-	long sem_otime;
-	unsigned long __unused1;
-	long sem_ctime;
-	unsigned long __unused2;
+	__syscall_long sem_otime; /* time_t */
+	unsigned __syscall_long __unused1;
+	__syscall_long sem_ctime; /* time_t */
+	unsigned __syscall_long __unused2;
 #if __BYTE_ORDER == __LITTLE_ENDIAN
 	unsigned short sem_nsems;
-	char __sem_nsems_pad[sizeof(long)-sizeof(short)];
+	char __sem_nsems_pad[sizeof(__syscall_long)-sizeof(short)];
 #else
-	char __sem_nsems_pad[sizeof(long)-sizeof(short)];
+	char __sem_nsems_pad[sizeof(__syscall_long)-sizeof(short)];
 	unsigned short sem_nsems;
 #endif
-	unsigned long __unused3;
-	unsigned long __unused4;
+	unsigned __syscall_long __unused3;
+	unsigned __syscall_long __unused4;
 };
 
 #define _SEM_SEMUN_UNDEFINED 1
diff --git a/include/sys/shm.h b/include/sys/shm.h
index c20f033..0a6b8f7 100644
--- a/include/sys/shm.h
+++ b/include/sys/shm.h
@@ -33,21 +33,27 @@ extern "C" {
 #define SHM_HUGETLB 04000
 #define SHM_NORESERVE 010000
 
+#ifdef __ILP32__ /* x32 */
+#define __syscall_long long long
+#else
+#define __syscall_long long
+#endif
+
 struct shminfo {
-	unsigned long shmmax, shmmin, shmmni, shmseg, shmall, __unused[4];
+	unsigned __syscall_long shmmax, shmmin, shmmni, shmseg, shmall, __unused[4];
 };
 
 struct shm_info {
 	int used_ids;
-	unsigned long shm_tot, shm_rss, shm_swp;
+	unsigned __syscall_long shm_tot, shm_rss, shm_swp;
 #ifdef _GNU_SOURCE
-	unsigned long swap_attempts, swap_successes;
+	unsigned __syscall_long swap_attempts, swap_successes;
 #else
-	unsigned long __reserved[2];
+	unsigned __syscall_long __reserved[2];
 #endif
 };
 
-typedef unsigned long shmatt_t;
+typedef unsigned __syscall_long shmatt_t;
 
 void *shmat(int, const void *, int);
 int shmctl(int, int, struct shmid_ds *);
diff --git a/src/internal/syscall.h b/src/internal/syscall.h
index 8eebe71..dea7797 100644
--- a/src/internal/syscall.h
+++ b/src/internal/syscall.h
@@ -4,19 +4,33 @@
 #if defined(__PIC__) && (100*__GNUC__+__GNUC_MINOR__ >= 303)
 __attribute__((visibility("protected")))
 #endif
-long __syscall_ret(unsigned long), __syscall(long, ...),
-	__syscall_cp(long, long, long, long, long, long, long);
+
+#ifdef __ILP32__
+#define __sl long long
+#else
+#define __sl long
+#endif
+
+long __syscall_ret(unsigned long), __syscall(__sl, ...),
+	__syscall_cp(__sl, __sl, __sl, __sl, __sl, __sl, __sl);
+
+#undef __sl
+#ifdef __ILP32__
+#define __sl unsigned long
+#else
+#define __sl long
+#endif
 
 #include <sys/syscall.h>
 #include "syscall_arch.h"
 
-#define __syscall1(n,a) __syscall1(n,(long)(a))
-#define __syscall2(n,a,b) __syscall2(n,(long)(a),(long)(b))
-#define __syscall3(n,a,b,c) __syscall3(n,(long)(a),(long)(b),(long)(c))
-#define __syscall4(n,a,b,c,d) __syscall4(n,(long)(a),(long)(b),(long)(c),(long)(d))
-#define __syscall5(n,a,b,c,d,e) __syscall5(n,(long)(a),(long)(b),(long)(c),(long)(d),(long)(e))
-#define __syscall6(n,a,b,c,d,e,f) __syscall6(n,(long)(a),(long)(b),(long)(c),(long)(d),(long)(e),(long)(f))
-#define __syscall7(n,a,b,c,d,e,f,g) (__syscall)(n,(long)(a),(long)(b),(long)(c),(long)(d),(long)(e),(long)(f),(long)g)
+#define __syscall1(n,a) __syscall1(n,(__sl)(a))
+#define __syscall2(n,a,b) __syscall2(n,(__sl)(a),(__sl)(b))
+#define __syscall3(n,a,b,c) __syscall3(n,(__sl)(a),(__sl)(b),(__sl)(c))
+#define __syscall4(n,a,b,c,d) __syscall4(n,(__sl)(a),(__sl)(b),(__sl)(c),(__sl)(d))
+#define __syscall5(n,a,b,c,d,e) __syscall5(n,(__sl)(a),(__sl)(b),(__sl)(c),(__sl)(d),(__sl)(e))
+#define __syscall6(n,a,b,c,d,e,f) __syscall6(n,(__sl)(a),(__sl)(b),(__sl)(c),(__sl)(d),(__sl)(e),(__sl)(f))
+#define __syscall7(n,a,b,c,d,e,f,g) (__syscall)(n,(__sl)(a),(__sl)(b),(__sl)(c),(__sl)(d),(__sl)(e),(__sl)(f),(__sl)g)
 
 #define __SYSCALL_NARGS_X(a,b,c,d,e,f,g,h,n,...) n
 #define __SYSCALL_NARGS(...) __SYSCALL_NARGS_X(__VA_ARGS__,7,6,5,4,3,2,1,0,)
@@ -31,12 +45,12 @@ long __syscall_ret(unsigned long), __syscall(long, ...),
 #define socketcall_cp __socketcall_cp
 
 #define __syscall_cp0(n) (__syscall_cp)(n,0,0,0,0,0,0)
-#define __syscall_cp1(n,a) (__syscall_cp)(n,(long)(a),0,0,0,0,0)
-#define __syscall_cp2(n,a,b) (__syscall_cp)(n,(long)(a),(long)(b),0,0,0,0)
-#define __syscall_cp3(n,a,b,c) (__syscall_cp)(n,(long)(a),(long)(b),(long)(c),0,0,0)
-#define __syscall_cp4(n,a,b,c,d) (__syscall_cp)(n,(long)(a),(long)(b),(long)(c),(long)(d),0,0)
-#define __syscall_cp5(n,a,b,c,d,e) (__syscall_cp)(n,(long)(a),(long)(b),(long)(c),(long)(d),(long)(e),0)
-#define __syscall_cp6(n,a,b,c,d,e,f) (__syscall_cp)(n,(long)(a),(long)(b),(long)(c),(long)(d),(long)(e),(long)(f))
+#define __syscall_cp1(n,a) (__syscall_cp)(n,(__sl)(a),0,0,0,0,0)
+#define __syscall_cp2(n,a,b) (__syscall_cp)(n,(__sl)(a),(__sl)(b),0,0,0,0)
+#define __syscall_cp3(n,a,b,c) (__syscall_cp)(n,(__sl)(a),(__sl)(b),(__sl)(c),0,0,0)
+#define __syscall_cp4(n,a,b,c,d) (__syscall_cp)(n,(__sl)(a),(__sl)(b),(__sl)(c),(__sl)(d),0,0)
+#define __syscall_cp5(n,a,b,c,d,e) (__syscall_cp)(n,(__sl)(a),(__sl)(b),(__sl)(c),(__sl)(d),(__sl)(e),0)
+#define __syscall_cp6(n,a,b,c,d,e,f) (__syscall_cp)(n,(__sl)(a),(__sl)(b),(__sl)(c),(__sl)(d),(__sl)(e),(__sl)(f))
 
 #define __syscall_cp(...) __SYSCALL_DISP(__syscall_cp,__VA_ARGS__)
 #define syscall_cp(...) __syscall_ret(__syscall_cp(__VA_ARGS__))
@@ -46,9 +60,9 @@ long __syscall_ret(unsigned long), __syscall(long, ...),
 #define __socketcall_cp(nm,a,b,c,d,e,f) syscall_cp(SYS_##nm, a, b, c, d, e, f)
 #else
 #define __socketcall(nm,a,b,c,d,e,f) syscall(SYS_socketcall, __SC_##nm, \
-    ((long [6]){ (long)a, (long)b, (long)c, (long)d, (long)e, (long)f }))
+    ((__sl [6]){ (__sl)a, (__sl)b, (__sl)c, (__sl)d, (__sl)e, (__sl)f }))
 #define __socketcall_cp(nm,a,b,c,d,e,f) syscall_cp(SYS_socketcall, __SC_##nm, \
-    ((long [6]){ (long)a, (long)b, (long)c, (long)d, (long)e, (long)f }))
+    ((__sl [6]){ (__sl)a, (__sl)b, (__sl)c, (__sl)d, (__sl)e, (__sl)f }))
 #endif
 
 /* fixup legacy 16-bit junk */
diff --git a/src/internal/x32/syscall.s b/src/internal/x32/syscall.s
new file mode 100644
index 0000000..6e0db09
--- /dev/null
+++ b/src/internal/x32/syscall.s
@@ -0,0 +1,12 @@
+.global __syscall
+.type __syscall,@function
+__syscall:
+	movq %rdi,%rax
+	movq %rsi,%rdi
+	movq %rdx,%rsi
+	movq %rcx,%rdx
+	movq %r8,%r10
+	movq %r9,%r8
+	movq 8(%rsp),%r9
+	syscall
+	ret
diff --git a/src/ldso/x32/dlsym.s b/src/ldso/x32/dlsym.s
new file mode 100644
index 0000000..3c16616
--- /dev/null
+++ b/src/ldso/x32/dlsym.s
@@ -0,0 +1,6 @@
+.text
+.global dlsym
+.type dlsym,@function
+dlsym:
+	mov (%rsp),%rdx
+	jmp __dlsym
diff --git a/src/ldso/x32/start.s b/src/ldso/x32/start.s
new file mode 100644
index 0000000..0fcf46d
--- /dev/null
+++ b/src/ldso/x32/start.s
@@ -0,0 +1,24 @@
+.text
+.global _start
+_start:
+	mov (%rsp),%rdi  /* move argc into 1st argument slot */
+	lea 4(%rsp),%rsi /* move argv into 2nd argument slot */
+	call __dynlink
+	/* in case the dynlinker was called directly, it sets the "consumed"
+	   argv values to -1. so we must loop over the array as long as -1
+	   is in the top argv slot, decrement argc, and then set the stackpointer
+	   to the new argc as well as argc's new value.
+	   as the x32 abi has longs in the argv array, we cannot use push/pop.*/
+	movl (%rsp),%edi /* copy argc into edi */
+	xor %rdx,%rdx /* we use rdx as an offset to the current argv member */
+1:	dec %edi
+	addl $4, %edx
+	movl (%rsp, %rdx), %esi
+	cmp $-1,%esi
+	jz 1b
+	inc %edi
+	subl $4, %edx
+	lea (%rsp, %rdx), %rsp /* set rsp to new argv[-1] */
+	movl %edi, (%rsp)      /* write new argc there */
+	xor %edx,%edx
+	jmp *%rax
diff --git a/src/process/x32/vfork.s b/src/process/x32/vfork.s
new file mode 100644
index 0000000..1039f0f
--- /dev/null
+++ b/src/process/x32/vfork.s
@@ -0,0 +1,12 @@
+.global __vfork
+.weak vfork
+.type __vfork,@function
+.type vfork,@function
+__vfork:
+vfork:
+	pop %rdx
+	mov $0x4000003a,%eax /* SYS_vfork */
+	syscall
+	push %rdx
+	mov %rax,%rdi
+	jmp __syscall_ret
diff --git a/src/setjmp/x32/longjmp.s b/src/setjmp/x32/longjmp.s
new file mode 100644
index 0000000..e175a4b
--- /dev/null
+++ b/src/setjmp/x32/longjmp.s
@@ -0,0 +1,22 @@
+/* Copyright 2011-2012 Nicholas J. Kain, licensed under standard MIT license */
+.global _longjmp
+.global longjmp
+.type _longjmp,@function
+.type longjmp,@function
+_longjmp:
+longjmp:
+	mov %rsi,%rax           /* val will be longjmp return */
+	test %rax,%rax
+	jnz 1f
+	inc %rax                /* if val==0, val=1 per longjmp semantics */
+1:
+	mov (%rdi),%rbx         /* rdi is the jmp_buf, restore regs from it */
+	mov 8(%rdi),%rbp
+	mov 16(%rdi),%r12
+	mov 24(%rdi),%r13
+	mov 32(%rdi),%r14
+	mov 40(%rdi),%r15
+	mov 48(%rdi),%rdx       /* this ends up being the stack pointer */
+	mov %rdx,%rsp
+	mov 56(%rdi),%rdx       /* this is the instruction pointer */
+	jmp *%rdx               /* goto saved address without altering rsp */
diff --git a/src/setjmp/x32/setjmp.s b/src/setjmp/x32/setjmp.s
new file mode 100644
index 0000000..98f58b8
--- /dev/null
+++ b/src/setjmp/x32/setjmp.s
@@ -0,0 +1,22 @@
+/* Copyright 2011-2012 Nicholas J. Kain, licensed under standard MIT license */
+.global __setjmp
+.global _setjmp
+.global setjmp
+.type __setjmp,@function
+.type _setjmp,@function
+.type setjmp,@function
+__setjmp:
+_setjmp:
+setjmp:
+	mov %rbx,(%rdi)         /* rdi is jmp_buf, move registers onto it */
+	mov %rbp,8(%rdi)
+	mov %r12,16(%rdi)
+	mov %r13,24(%rdi)
+	mov %r14,32(%rdi)
+	mov %r15,40(%rdi)
+	lea 8(%rsp),%rdx        /* this is our rsp WITHOUT current ret addr */
+	mov %rdx,48(%rdi)
+	mov (%rsp),%rdx         /* save return addr ptr for new rip */
+	mov %rdx,56(%rdi)
+	xor %rax,%rax           /* always return 0 */
+	ret
diff --git a/src/signal/x32/restore.s b/src/signal/x32/restore.s
new file mode 100644
index 0000000..27cd3ce
--- /dev/null
+++ b/src/signal/x32/restore.s
@@ -0,0 +1,8 @@
+.global __restore_rt
+.global __restore
+.type __restore_rt,@function
+.type __restore,@function
+__restore_rt:
+__restore:
+	movl $0x40000201, %eax /* SYS_rt_sigreturn */
+	syscall
diff --git a/src/signal/x32/sigsetjmp.s b/src/signal/x32/sigsetjmp.s
new file mode 100644
index 0000000..dc38f03
--- /dev/null
+++ b/src/signal/x32/sigsetjmp.s
@@ -0,0 +1,14 @@
+/* Copyright 2011-2012 Nicholas J. Kain, licensed under standard MIT license */
+.global sigsetjmp
+.type sigsetjmp,@function
+sigsetjmp:
+	andl %esi,%esi
+	movq %rsi,64(%rdi)
+	jz 1f
+	pushq %rdi
+	leaq 72(%rdi),%rdx
+	xorl %esi,%esi
+	movl $2,%edi
+	call sigprocmask
+	popq %rdi
+1:	jmp setjmp
diff --git a/src/thread/cancel_dummy.c b/src/thread/cancel_dummy.c
index 047692c..6046367 100644
--- a/src/thread/cancel_dummy.c
+++ b/src/thread/cancel_dummy.c
@@ -1,6 +1,13 @@
 #include "pthread_impl.h"
+#ifdef __ILP32__
+#define __syscall_long long long
+#else
+#define __syscall_long long
+#endif
 
-static long sccp(long nr, long u, long v, long w, long x, long y, long z)
+static long sccp(__syscall_long nr, __syscall_long u,
+                           __syscall_long v, __syscall_long w,
+                           __syscall_long x, __syscall_long y, __syscall_long z)
 {
 	return (__syscall)(nr, u, v, w, x, y, z);
 }
diff --git a/src/thread/cancel_impl.c b/src/thread/cancel_impl.c
index a164898..d530c2f 100644
--- a/src/thread/cancel_impl.c
+++ b/src/thread/cancel_impl.c
@@ -8,12 +8,18 @@ void __cancel()
 	pthread_exit(PTHREAD_CANCELED);
 }
 
-long __syscall_cp_asm(volatile void *, long, long, long, long, long, long, long);
+#undef __sl
+#ifdef __ILP32__
+#define __sl long long
+#else
+#define __sl long
+#endif
+long __syscall_cp_asm(volatile void *, __sl, __sl, __sl, __sl, __sl, __sl, __sl);
 
-long (__syscall_cp)(long nr, long u, long v, long w, long x, long y, long z)
+long (__syscall_cp)(__sl nr, __sl u, __sl v, __sl w, __sl x, __sl y, __sl z)
 {
 	pthread_t self;
-	long r;
+	__sl r;
 
 	if (!libc.main_thread || (self = __pthread_self())->canceldisable)
 		return __syscall(nr, u, v, w, x, y, z);
diff --git a/src/thread/x32/__set_thread_area.s b/src/thread/x32/__set_thread_area.s
new file mode 100644
index 0000000..f3ff4f6
--- /dev/null
+++ b/src/thread/x32/__set_thread_area.s
@@ -0,0 +1,10 @@
+/* Copyright 2011-2012 Nicholas J. Kain, licensed under standard MIT license */
+.text
+.global __set_thread_area
+.type __set_thread_area,@function
+__set_thread_area:
+	mov %rdi,%rsi           /* shift for syscall */
+	movl $0x1002,%edi       /* SET_FS register */
+	movl $158,%eax          /* set fs segment to */
+	syscall                 /* arch_prctl(SET_FS, arg)*/
+	ret
diff --git a/src/thread/x32/__unmapself.s b/src/thread/x32/__unmapself.s
new file mode 100644
index 0000000..d925460
--- /dev/null
+++ b/src/thread/x32/__unmapself.s
@@ -0,0 +1,10 @@
+/* Copyright 2011-2012 Nicholas J. Kain, licensed under standard MIT license */
+.text
+.global __unmapself
+.type   __unmapself,@function
+__unmapself:
+	movl $0x4000000b,%eax   /* SYS_munmap */
+	syscall         /* munmap(arg2,arg3) */
+	xor %rdi,%rdi   /* exit() args: always return success */
+	movl $0x4000003c,%eax   /* SYS_exit */
+	syscall         /* exit(0) */
diff --git a/src/thread/x32/clone.s b/src/thread/x32/clone.s
new file mode 100644
index 0000000..55fd9d4
--- /dev/null
+++ b/src/thread/x32/clone.s
@@ -0,0 +1,28 @@
+.text
+.global __clone
+.weak clone
+.type   __clone,@function
+.type   clone,@function
+__clone:
+clone:
+	movl $0x40000038,%eax /* SYS_clone */
+	mov %rdi,%r11
+	mov %rdx,%rdi
+	mov %r8,%rdx
+	mov %r9,%r8
+	mov 8(%rsp),%r10
+	mov %r11,%r9
+	and $-16,%rsi
+	sub $8,%rsi
+	mov %rcx,(%rsi)
+	syscall
+	test %eax,%eax
+	jnz 1f
+	xor %ebp,%ebp
+	pop %rdi
+	call *%r9
+	mov %eax,%edi
+	movl $0x4000003c,%eax /* SYS_exit */
+	syscall
+	hlt
+1:	ret
diff --git a/src/thread/x32/syscall_cp.s b/src/thread/x32/syscall_cp.s
new file mode 100644
index 0000000..788c53c
--- /dev/null
+++ b/src/thread/x32/syscall_cp.s
@@ -0,0 +1,23 @@
+.text
+.global __syscall_cp_asm
+.type   __syscall_cp_asm,@function
+__syscall_cp_asm:
+
+.global __cp_begin
+__cp_begin:
+	mov (%rdi),%eax
+	test %eax,%eax
+	jnz __cancel
+	mov %rdi,%r11
+	mov %rsi,%rax
+	mov %rdx,%rdi
+	mov %rcx,%rsi
+	mov %r8,%rdx
+	mov %r9,%r10
+	mov 8(%rsp),%r8
+	mov 16(%rsp),%r9
+	mov %r11,8(%rsp)
+	syscall
+.global __cp_end
+__cp_end:
+	ret
-- 
1.8.4


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2013-12-28  0:07 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-12-28  0:07 [RFC][PATCH] x32: initial draft of port John Spencer

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