Follow @Openwall on Twitter for new release announcements and other news
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20240506180112.1045944-2-jcmvbkbc@gmail.com>
Date: Mon,  6 May 2024 11:01:12 -0700
From: Max Filippov <jcmvbkbc@...il.com>
To: musl@...ts.openwall.com
Cc: Rich Felker <dalias@...c.org>,
	Max Filippov <jcmvbkbc@...il.com>
Subject: [RFC v3 1/1] xtensa: add port

Signed-off-by: Max Filippov <jcmvbkbc@...il.com>
---
Changes v2->v3:
- fix semid_ds::sem_nsems type
- drop store to GOT entry at offset 12 from arch/xtensa/crt_arch.h
- add alignment to all assembly function entry points
- add .literal_position directive to vfork

Changes v1->v2:
- rebase to 1.2.5
- drop xtensa-config.h, use __XCHAL_* macros directly where needed
- fix max_align_t definition
- drop duplications from arch/xtensa/bits/mman.h
- drop xtensa call0/windowed ABI ifdef checks
- fix mcontext_t definition
- drop endianness indication from the LDSO_ARCH string
- rewrite __tlsdesc_dynamic implementation
- fix sigsetjmp
- rewrite __set_thread_area as C function
- fix ctid argument fetch in __clone implementation
- drop arch/xtensa/bits/termios.h
- add arch/xtensa/bits/msg.h, arch/xtensa/bits/sem.h,
  arch/xtensa/bits/shm.h and arch/xtensa/bits/ipcstat.h
- add src/ldso/xtensa/dlsym.s and src/ldso/xtensa/dlsym_time64.S
- add arch/xtensa/bits/poll.h
- replace REL_RELATIVE with REL_SYMBOLIC
---
 arch/xtensa/arch.mak                  |   1 +
 arch/xtensa/atomic_arch.h             |  25 ++
 arch/xtensa/bits/alltypes.h.in        |  27 ++
 arch/xtensa/bits/float.h              |  16 +
 arch/xtensa/bits/ioctl.h              | 219 ++++++++++++++
 arch/xtensa/bits/ipcstat.h            |   1 +
 arch/xtensa/bits/limits.h             |   1 +
 arch/xtensa/bits/mman.h               |  20 ++
 arch/xtensa/bits/msg.h                |  27 ++
 arch/xtensa/bits/poll.h               |   3 +
 arch/xtensa/bits/posix.h              |   2 +
 arch/xtensa/bits/reg.h                |   2 +
 arch/xtensa/bits/sem.h                |  22 ++
 arch/xtensa/bits/setjmp.h             |   1 +
 arch/xtensa/bits/shm.h                |  29 ++
 arch/xtensa/bits/signal.h             |  92 ++++++
 arch/xtensa/bits/stat.h               |  23 ++
 arch/xtensa/bits/stdint.h             |  20 ++
 arch/xtensa/bits/syscall.h.in         | 407 ++++++++++++++++++++++++++
 arch/xtensa/bits/user.h               |   4 +
 arch/xtensa/crt_arch.h                |  47 +++
 arch/xtensa/kstat.h                   |  18 ++
 arch/xtensa/pthread_arch.h            |  11 +
 arch/xtensa/reloc.h                   |  32 ++
 arch/xtensa/syscall_arch.h            | 104 +++++++
 configure                             |   8 +
 crt/xtensa/crti.S                     |  23 ++
 crt/xtensa/crtn.S                     |  15 +
 include/elf.h                         |  74 +++++
 src/internal/xtensa/syscall.s         |  14 +
 src/ldso/xtensa/dlsym.s               |   7 +
 src/ldso/xtensa/dlsym_time64.S        |   3 +
 src/ldso/xtensa/tlsdesc.s             |  25 ++
 src/process/xtensa/vfork.s            |  15 +
 src/setjmp/xtensa/longjmp.s           |  18 ++
 src/setjmp/xtensa/setjmp.s            |  21 ++
 src/signal/xtensa/restore.s           |  10 +
 src/signal/xtensa/sigsetjmp.s         |  22 ++
 src/thread/xtensa/__set_thread_area.c |   9 +
 src/thread/xtensa/__unmapself.s       |   9 +
 src/thread/xtensa/clone.S             |  42 +++
 src/thread/xtensa/syscall_cp.s        |  34 +++
 42 files changed, 1503 insertions(+)
 create mode 100644 arch/xtensa/arch.mak
 create mode 100644 arch/xtensa/atomic_arch.h
 create mode 100644 arch/xtensa/bits/alltypes.h.in
 create mode 100644 arch/xtensa/bits/float.h
 create mode 100644 arch/xtensa/bits/ioctl.h
 create mode 100644 arch/xtensa/bits/ipcstat.h
 create mode 100644 arch/xtensa/bits/limits.h
 create mode 100644 arch/xtensa/bits/mman.h
 create mode 100644 arch/xtensa/bits/msg.h
 create mode 100644 arch/xtensa/bits/poll.h
 create mode 100644 arch/xtensa/bits/posix.h
 create mode 100644 arch/xtensa/bits/reg.h
 create mode 100644 arch/xtensa/bits/sem.h
 create mode 100644 arch/xtensa/bits/setjmp.h
 create mode 100644 arch/xtensa/bits/shm.h
 create mode 100644 arch/xtensa/bits/signal.h
 create mode 100644 arch/xtensa/bits/stat.h
 create mode 100644 arch/xtensa/bits/stdint.h
 create mode 100644 arch/xtensa/bits/syscall.h.in
 create mode 100644 arch/xtensa/bits/user.h
 create mode 100644 arch/xtensa/crt_arch.h
 create mode 100644 arch/xtensa/kstat.h
 create mode 100644 arch/xtensa/pthread_arch.h
 create mode 100644 arch/xtensa/reloc.h
 create mode 100644 arch/xtensa/syscall_arch.h
 create mode 100644 crt/xtensa/crti.S
 create mode 100644 crt/xtensa/crtn.S
 create mode 100644 src/internal/xtensa/syscall.s
 create mode 100644 src/ldso/xtensa/dlsym.s
 create mode 100644 src/ldso/xtensa/dlsym_time64.S
 create mode 100644 src/ldso/xtensa/tlsdesc.s
 create mode 100644 src/process/xtensa/vfork.s
 create mode 100644 src/setjmp/xtensa/longjmp.s
 create mode 100644 src/setjmp/xtensa/setjmp.s
 create mode 100644 src/signal/xtensa/restore.s
 create mode 100644 src/signal/xtensa/sigsetjmp.s
 create mode 100644 src/thread/xtensa/__set_thread_area.c
 create mode 100644 src/thread/xtensa/__unmapself.s
 create mode 100644 src/thread/xtensa/clone.S
 create mode 100644 src/thread/xtensa/syscall_cp.s

diff --git a/arch/xtensa/arch.mak b/arch/xtensa/arch.mak
new file mode 100644
index 000000000000..aa4d05ceff38
--- /dev/null
+++ b/arch/xtensa/arch.mak
@@ -0,0 +1 @@
+COMPAT_SRC_DIRS = compat/time32
diff --git a/arch/xtensa/atomic_arch.h b/arch/xtensa/atomic_arch.h
new file mode 100644
index 000000000000..ece0f5b19456
--- /dev/null
+++ b/arch/xtensa/atomic_arch.h
@@ -0,0 +1,25 @@
+#if __XCHAL_HAVE_S32C1I
+#define a_cas a_cas
+static inline int a_cas(volatile int *p, int t, int s)
+{
+	__asm__ __volatile__ (
+		"	wsr	%2, scompare1\n"
+		"	s32c1i	%0, %1\n"
+		: "+a"(s), "+m"(*p)
+		: "a"(t)
+		: "memory" );
+        return s;
+}
+#endif
+
+#define a_barrier a_barrier
+static inline void a_barrier()
+{
+	__asm__ __volatile__ ("memw" : : : "memory");
+}
+
+#define a_crash a_crash
+static inline void a_crash()
+{
+	__asm__ __volatile__ ("ill" : : : "memory");
+}
diff --git a/arch/xtensa/bits/alltypes.h.in b/arch/xtensa/bits/alltypes.h.in
new file mode 100644
index 000000000000..24f4d20995af
--- /dev/null
+++ b/arch/xtensa/bits/alltypes.h.in
@@ -0,0 +1,27 @@
+#define _REDIR_TIME64 1
+#define _Addr int
+#define _Int64 long long
+#define _Reg int
+
+#if __XTENSA_EB__
+#define __BYTE_ORDER 4321
+#elif __XTENSA_EL__
+#define __BYTE_ORDER 1234
+#else
+#error Unknown endianness
+#endif
+
+#define __LONG_MAX 0x7fffffffL
+
+#ifndef __cplusplus
+#ifdef __WCHAR_TYPE__
+TYPEDEF __WCHAR_TYPE__ wchar_t;
+#else
+TYPEDEF unsigned wchar_t;
+#endif
+#endif
+
+TYPEDEF float float_t;
+TYPEDEF double double_t;
+
+TYPEDEF struct { long long __ll; long double __ld; } max_align_t;
diff --git a/arch/xtensa/bits/float.h b/arch/xtensa/bits/float.h
new file mode 100644
index 000000000000..c4a655e7b58c
--- /dev/null
+++ b/arch/xtensa/bits/float.h
@@ -0,0 +1,16 @@
+#define FLT_EVAL_METHOD 0
+
+#define LDBL_TRUE_MIN 4.94065645841246544177e-324L
+#define LDBL_MIN 2.22507385850720138309e-308L
+#define LDBL_MAX 1.79769313486231570815e+308L
+#define LDBL_EPSILON 2.22044604925031308085e-16L
+
+#define LDBL_MANT_DIG 53
+#define LDBL_MIN_EXP (-1021)
+#define LDBL_MAX_EXP 1024
+
+#define LDBL_DIG 15
+#define LDBL_MIN_10_EXP (-307)
+#define LDBL_MAX_10_EXP 308
+
+#define DECIMAL_DIG 17
diff --git a/arch/xtensa/bits/ioctl.h b/arch/xtensa/bits/ioctl.h
new file mode 100644
index 000000000000..f30e3a699bf8
--- /dev/null
+++ b/arch/xtensa/bits/ioctl.h
@@ -0,0 +1,219 @@
+#define _IOC(a,b,c,d) ( ((a)<<30) | ((b)<<8) | (c) | ((d)<<16) )
+#define _IOC_NONE  0U
+#define _IOC_READ  2U
+#define _IOC_WRITE 1U
+
+#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 FIOCLEX		_IO('f', 1)
+#define FIONCLEX	_IO('f', 2)
+#define FIOASYNC	_IOW('f', 125, int)
+#define FIONBIO		_IOW('f', 126, int)
+#define FIONREAD	_IOR('f', 127, int)
+#define TIOCINQ		FIONREAD
+#define FIOQSIZE	_IOR('f', 128, loff_t)
+
+#define TCGETS		0x5401
+#define TCSETS		0x5402
+#define TCSETSW		0x5403
+#define TCSETSF		0x5404
+
+#define TCGETA		0x80127417	/* _IOR('t', 23, struct termio) */
+#define TCSETA		0x40127418	/* _IOW('t', 24, struct termio) */
+#define TCSETAW		0x40127419	/* _IOW('t', 25, struct termio) */
+#define TCSETAF		0x4012741C	/* _IOW('t', 28, struct termio) */
+
+#define TCSBRK		_IO('t', 29)
+#define TCXONC		_IO('t', 30)
+#define TCFLSH		_IO('t', 31)
+
+#define TIOCSWINSZ	0x40087467	/* _IOW('t', 103, struct winsize) */
+#define TIOCGWINSZ	0x80087468	/* _IOR('t', 104, struct winsize) */
+#define	TIOCSTART	_IO('t', 110)		/* start output, like ^Q */
+#define	TIOCSTOP	_IO('t', 111)		/* stop output, like ^S */
+#define TIOCOUTQ        _IOR('t', 115, int)     /* output queue size */
+
+#define TIOCSPGRP	_IOW('t', 118, int)
+#define TIOCGPGRP	_IOR('t', 119, int)
+
+#define TIOCEXCL	_IO('T', 12)
+#define TIOCNXCL	_IO('T', 13)
+#define TIOCSCTTY	_IO('T', 14)
+
+#define TIOCSTI		_IOW('T', 18, char)
+#define TIOCMGET	_IOR('T', 21, unsigned int)
+#define TIOCMBIS	_IOW('T', 22, unsigned int)
+#define TIOCMBIC	_IOW('T', 23, unsigned int)
+#define TIOCMSET	_IOW('T', 24, unsigned int)
+# 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 TIOCGSOFTCAR	_IOR('T', 25, unsigned int)
+#define TIOCSSOFTCAR	_IOW('T', 26, unsigned int)
+#define TIOCLINUX	_IOW('T', 28, char)
+#define TIOCCONS	_IO('T', 29)
+#define TIOCGSERIAL	0x803C541E	/*_IOR('T', 30, struct serial_struct)*/
+#define TIOCSSERIAL	0x403C541F	/*_IOW('T', 31, struct serial_struct)*/
+#define TIOCPKT		_IOW('T', 32, int)
+# 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 TIOCNOTTY	_IO('T', 34)
+#define TIOCSETD	_IOW('T', 35, int)
+#define TIOCGETD	_IOR('T', 36, int)
+#define TCSBRKP		_IOW('T', 37, int)   /* Needed for POSIX tcsendbreak()*/
+#define TIOCSBRK	_IO('T', 39) 	     /* BSD compatibility */
+#define TIOCCBRK	_IO('T', 40)	     /* BSD compatibility */
+#define TIOCGSID	_IOR('T', 41, pid_t) /* Return the session ID of FD*/
+#define TCGETS2		_IOR('T', 42, struct termios2)
+#define TCSETS2		_IOW('T', 43, struct termios2)
+#define TCSETSW2	_IOW('T', 44, struct termios2)
+#define TCSETSF2	_IOW('T', 45, struct termios2)
+#define TIOCGRS485	_IOR('T', 46, struct serial_rs485)
+#define TIOCSRS485	_IOWR('T', 47, struct serial_rs485)
+#define TIOCGPTN	_IOR('T',0x30, unsigned int) /* Get Pty Number (of pty-mux device) */
+#define TIOCSPTLCK	_IOW('T',0x31, int)  /* Lock/unlock Pty */
+#define TIOCGDEV	_IOR('T',0x32, unsigned int) /* Get primary device node of /dev/console */
+#define TIOCSIG		_IOW('T',0x36, int)  /* Generate signal on Pty slave */
+#define TIOCVHANGUP	_IO('T', 0x37)
+#define TIOCGPKT	_IOR('T', 0x38, int) /* Get packet mode state */
+#define TIOCGPTLCK	_IOR('T', 0x39, int) /* Get Pty lock state */
+#define TIOCGEXCL	_IOR('T', 0x40, int) /* Get exclusive mode state */
+
+#define TIOCSERCONFIG	_IO('T', 83)
+#define TIOCSERGWILD	_IOR('T', 84,  int)
+#define TIOCSERSWILD	_IOW('T', 85,  int)
+#define TIOCGLCKTRMIOS	0x5456
+#define TIOCSLCKTRMIOS	0x5457
+#define TIOCSERGSTRUCT	0x5458		     /* For debugging only */
+#define TIOCSERGETLSR   _IOR('T', 89, unsigned int) /* Get line status reg. */
+  /* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */
+#define TIOCSERGETMULTI 0x80a8545a /* Get multiport config  */
+			/* _IOR('T', 90, struct serial_multiport_struct) */
+#define TIOCSERSETMULTI 0x40a8545b /* Set multiport config */
+			/* _IOW('T', 91, struct serial_multiport_struct) */
+
+#define TIOCMIWAIT	_IO('T', 92) /* wait for a change on serial input line(s) */
+#define TIOCGICOUNT	0x545D	/* read serial port inline interrupt counts */
+
+#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 FIOGETOWN	_IOR('f', 123, int)
+#define FIOSETOWN 	_IOW('f', 124, int)
+#define SIOCATMARK	_IOR('s', 7, int)
+#define SIOCSPGRP	_IOW('s', 8, pid_t)
+#define SIOCGPGRP	_IOR('s', 9, pid_t)
+#define SIOCGSTAMP	0x8906		/* Get stamp (timeval) */
+#define SIOCGSTAMPNS	0x8907		/* Get stamp (timespec) */
+
+#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/xtensa/bits/ipcstat.h b/arch/xtensa/bits/ipcstat.h
new file mode 100644
index 000000000000..4f4fcb0c5b74
--- /dev/null
+++ b/arch/xtensa/bits/ipcstat.h
@@ -0,0 +1 @@
+#define IPC_STAT 0x102
diff --git a/arch/xtensa/bits/limits.h b/arch/xtensa/bits/limits.h
new file mode 100644
index 000000000000..07743b6fd61f
--- /dev/null
+++ b/arch/xtensa/bits/limits.h
@@ -0,0 +1 @@
+#define PAGESIZE 4096
diff --git a/arch/xtensa/bits/mman.h b/arch/xtensa/bits/mman.h
new file mode 100644
index 000000000000..0cc7b46b0740
--- /dev/null
+++ b/arch/xtensa/bits/mman.h
@@ -0,0 +1,20 @@
+#undef MAP_ANON
+#define MAP_ANON       0x800
+#undef MAP_NORESERVE
+#define MAP_NORESERVE  0x0400
+#undef MAP_GROWSDOWN
+#define MAP_GROWSDOWN  0x1000
+#undef MAP_DENYWRITE
+#define MAP_DENYWRITE  0x2000
+#undef MAP_EXECUTABLE
+#define MAP_EXECUTABLE 0x4000
+#undef MAP_LOCKED
+#define MAP_LOCKED     0x8000
+#undef MAP_POPULATE
+#define MAP_POPULATE   0x10000
+#undef MAP_NONBLOCK
+#define MAP_NONBLOCK   0x20000
+#undef MAP_STACK
+#define MAP_STACK      0x40000
+#undef MAP_HUGETLB
+#define MAP_HUGETLB    0x80000
diff --git a/arch/xtensa/bits/msg.h b/arch/xtensa/bits/msg.h
new file mode 100644
index 000000000000..f05f280b65e1
--- /dev/null
+++ b/arch/xtensa/bits/msg.h
@@ -0,0 +1,27 @@
+struct msqid_ds {
+	struct ipc_perm msg_perm;
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+	unsigned long __msg_stime_lo;
+	unsigned long __msg_stime_hi;
+	unsigned long __msg_rtime_lo;
+	unsigned long __msg_rtime_hi;
+	unsigned long __msg_ctime_lo;
+	unsigned long __msg_ctime_hi;
+#else
+	unsigned long __msg_stime_hi;
+	unsigned long __msg_stime_lo;
+	unsigned long __msg_rtime_hi;
+	unsigned long __msg_rtime_lo;
+	unsigned long __msg_ctime_hi;
+	unsigned long __msg_ctime_lo;
+#endif
+	unsigned long msg_cbytes;
+	msgqnum_t msg_qnum;
+	msglen_t msg_qbytes;
+	pid_t msg_lspid;
+	pid_t msg_lrpid;
+	unsigned long __unused[2];
+	time_t msg_stime;
+	time_t msg_rtime;
+	time_t msg_ctime;
+};
diff --git a/arch/xtensa/bits/poll.h b/arch/xtensa/bits/poll.h
new file mode 100644
index 000000000000..939398a79aa2
--- /dev/null
+++ b/arch/xtensa/bits/poll.h
@@ -0,0 +1,3 @@
+#define POLLWRNORM POLLOUT
+#define POLLWRBAND 0x100
+#define POLLREMOVE 0x800
diff --git a/arch/xtensa/bits/posix.h b/arch/xtensa/bits/posix.h
new file mode 100644
index 000000000000..30a38714f36d
--- /dev/null
+++ b/arch/xtensa/bits/posix.h
@@ -0,0 +1,2 @@
+#define _POSIX_V6_ILP32_OFFBIG  1
+#define _POSIX_V7_ILP32_OFFBIG  1
diff --git a/arch/xtensa/bits/reg.h b/arch/xtensa/bits/reg.h
new file mode 100644
index 000000000000..0192a2931bd7
--- /dev/null
+++ b/arch/xtensa/bits/reg.h
@@ -0,0 +1,2 @@
+#undef __WORDSIZE
+#define __WORDSIZE 32
diff --git a/arch/xtensa/bits/sem.h b/arch/xtensa/bits/sem.h
new file mode 100644
index 000000000000..57aa020ad96e
--- /dev/null
+++ b/arch/xtensa/bits/sem.h
@@ -0,0 +1,22 @@
+struct semid_ds {
+	struct ipc_perm sem_perm;
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+	unsigned long __sem_otime_lo;
+	unsigned long __sem_otime_hi;
+	unsigned long __sem_ctime_lo;
+	unsigned long __sem_ctime_hi;
+	unsigned short sem_nsems;
+	unsigned short __unused;
+#else
+	unsigned long __sem_otime_hi;
+	unsigned long __sem_otime_lo;
+	unsigned long __sem_ctime_hi;
+	unsigned long __sem_ctime_lo;
+	unsigned short __unused;
+	unsigned short sem_nsems;
+#endif
+	long __unused3;
+	long __unused4;
+	time_t sem_otime;
+	time_t sem_ctime;
+};
diff --git a/arch/xtensa/bits/setjmp.h b/arch/xtensa/bits/setjmp.h
new file mode 100644
index 000000000000..decd26dca07a
--- /dev/null
+++ b/arch/xtensa/bits/setjmp.h
@@ -0,0 +1 @@
+typedef unsigned long __jmp_buf[6];
diff --git a/arch/xtensa/bits/shm.h b/arch/xtensa/bits/shm.h
new file mode 100644
index 000000000000..2febc663f709
--- /dev/null
+++ b/arch/xtensa/bits/shm.h
@@ -0,0 +1,29 @@
+#define SHMLBA 4096
+
+struct shmid_ds {
+	struct ipc_perm shm_perm;
+	size_t shm_segsz;
+	unsigned long __shm_atime_lo;
+	unsigned long __shm_atime_hi;
+	unsigned long __shm_dtime_lo;
+	unsigned long __shm_dtime_hi;
+	unsigned long __shm_ctime_lo;
+	unsigned long __shm_ctime_hi;
+	pid_t shm_cpid;
+	pid_t shm_lpid;
+	unsigned long shm_nattch;
+	unsigned long __unused[2];
+	time_t shm_atime;
+	time_t shm_dtime;
+	time_t shm_ctime;
+};
+
+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/xtensa/bits/signal.h b/arch/xtensa/bits/signal.h
new file mode 100644
index 000000000000..aa1b958abc9a
--- /dev/null
+++ b/arch/xtensa/bits/signal.h
@@ -0,0 +1,92 @@
+#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 2048
+#define SIGSTKSZ 8192
+#endif
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+typedef struct sigcontext {
+	unsigned long sc_pc;
+	unsigned long sc_ps;
+	unsigned long sc_lbeg;
+	unsigned long sc_lend;
+	unsigned long sc_lcount;
+	unsigned long sc_sar;
+	unsigned long sc_acclo;
+	unsigned long sc_acchi;
+	unsigned long sc_a[16];
+	void *sc_xtregs;
+} mcontext_t;
+#else
+typedef struct {
+	unsigned long __regs[25];
+} 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	0x00000001
+#define SA_NOCLDWAIT	0x00000002 /* not supported yet */
+#define SA_SIGINFO	0x00000004
+#define SA_ONSTACK	0x08000000
+#define SA_RESTART	0x10000000
+#define SA_NODEFER	0x40000000
+#define SA_RESETHAND	0x80000000
+
+#define SA_NOMASK	SA_NODEFER
+#define SA_ONESHOT	SA_RESETHAND
+
+#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		 6
+#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	31
+
+#define _NSIG 65
diff --git a/arch/xtensa/bits/stat.h b/arch/xtensa/bits/stat.h
new file mode 100644
index 000000000000..31d92fec1232
--- /dev/null
+++ b/arch/xtensa/bits/stat.h
@@ -0,0 +1,23 @@
+/* copied from kernel definition, but with padding replaced
+ * by the corresponding correctly-sized userspace types. */
+
+struct stat {
+	dev_t st_dev;
+	ino_t st_ino;
+	mode_t st_mode;
+	nlink_t st_nlink;
+	uid_t st_uid;
+	gid_t st_gid;
+	dev_t st_rdev;
+	off_t st_size;
+	blksize_t st_blksize;
+	long __st_padding1;
+	blkcnt_t st_blocks;
+	struct {
+		long tv_sec;
+		long tv_nsec;
+	} __st_atim32, __st_mtim32, __st_ctim32;
+	struct timespec st_atim;
+	struct timespec st_mtim;
+	struct timespec st_ctim;
+};
diff --git a/arch/xtensa/bits/stdint.h b/arch/xtensa/bits/stdint.h
new file mode 100644
index 000000000000..d1b2712199ac
--- /dev/null
+++ b/arch/xtensa/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/xtensa/bits/syscall.h.in b/arch/xtensa/bits/syscall.h.in
new file mode 100644
index 000000000000..ec3135e12b07
--- /dev/null
+++ b/arch/xtensa/bits/syscall.h.in
@@ -0,0 +1,407 @@
+#define __NR_spill				  0
+#define __NR_xtensa				  1
+#define __NR_available4				  2
+#define __NR_available5				  3
+#define __NR_available6				  4
+#define __NR_available7				  5
+#define __NR_available8				  6
+#define __NR_available9				  7
+#define __NR_open				  8
+#define __NR_close				  9
+#define __NR_dup				 10
+#define __NR_dup2				 11
+#define __NR_read				 12
+#define __NR_write				 13
+#define __NR_select				 14
+#define __NR_lseek				 15
+#define __NR_poll				 16
+#define __NR__llseek				 17
+#define __NR_epoll_wait				 18
+#define __NR_epoll_ctl				 19
+#define __NR_epoll_create			 20
+#define __NR_creat				 21
+#define __NR_truncate				 22
+#define __NR_ftruncate				 23
+#define __NR_readv				 24
+#define __NR_writev				 25
+#define __NR_fsync				 26
+#define __NR_fdatasync				 27
+#define __NR_truncate64				 28
+#define __NR_ftruncate64			 29
+#define __NR_pread64				 30
+#define __NR_pwrite64				 31
+#define __NR_link				 32
+#define __NR_rename				 33
+#define __NR_symlink				 34
+#define __NR_readlink				 35
+#define __NR_mknod				 36
+#define __NR_pipe				 37
+#define __NR_unlink				 38
+#define __NR_rmdir				 39
+#define __NR_mkdir				 40
+#define __NR_chdir				 41
+#define __NR_fchdir				 42
+#define __NR_getcwd				 43
+#define __NR_chmod				 44
+#define __NR_chown				 45
+#define __NR_stat				 46
+#define __NR_stat64				 47
+#define __NR_lchown				 48
+#define __NR_lstat				 49
+#define __NR_lstat64				 50
+#define __NR_available51			 51
+#define __NR_fchmod				 52
+#define __NR_fchown				 53
+#define __NR_fstat				 54
+#define __NR_fstat64				 55
+#define __NR_flock				 56
+#define __NR_access				 57
+#define __NR_umask				 58
+#define __NR_getdents				 59
+#define __NR_getdents64				 60
+#define __NR_fcntl64				 61
+#define __NR_fallocate				 62
+#define __NR_fadvise64_64			 63
+#define __NR_utime				 64	/* glibc 2.3.3 ?? */
+#define __NR_utimes				 65
+#define __NR_ioctl				 66
+#define __NR_fcntl				 67
+#define __NR_setxattr				 68
+#define __NR_getxattr				 69
+#define __NR_listxattr				 70
+#define __NR_removexattr			 71
+#define __NR_lsetxattr				 72
+#define __NR_lgetxattr				 73
+#define __NR_llistxattr				 74
+#define __NR_lremovexattr			 75
+#define __NR_fsetxattr				 76
+#define __NR_fgetxattr				 77
+#define __NR_flistxattr				 78
+#define __NR_fremovexattr			 79
+#define __NR_mmap2				 80
+#define __NR_munmap				 81
+#define __NR_mprotect				 82
+#define __NR_brk				 83
+#define __NR_mlock				 84
+#define __NR_munlock				 85
+#define __NR_mlockall				 86
+#define __NR_munlockall				 87
+#define __NR_mremap				 88
+#define __NR_msync				 89
+#define __NR_mincore				 90
+#define __NR_madvise				 91
+#define __NR_shmget				 92
+#define __NR_shmat				 93
+#define __NR_shmctl				 94
+#define __NR_shmdt				 95
+#define __NR_socket				 96
+#define __NR_setsockopt				 97
+#define __NR_getsockopt				 98
+#define __NR_shutdown				 99
+#define __NR_bind				100
+#define __NR_connect				101
+#define __NR_listen				102
+#define __NR_accept				103
+#define __NR_getsockname			104
+#define __NR_getpeername			105
+#define __NR_sendmsg				106
+#define __NR_recvmsg				107
+#define __NR_send				108
+#define __NR_recv				109
+#define __NR_sendto				110
+#define __NR_recvfrom				111
+#define __NR_socketpair				112
+#define __NR_sendfile				113
+#define __NR_sendfile64				114
+#define __NR_sendmmsg				115
+#define __NR_clone				116
+#define __NR_execve				117
+#define __NR_exit				118
+#define __NR_exit_group				119
+#define __NR_getpid				120
+#define __NR_wait4				121
+#define __NR_waitid				122
+#define __NR_kill				123
+#define __NR_tkill				124
+#define __NR_tgkill				125
+#define __NR_set_tid_address			126
+#define __NR_gettid				127
+#define __NR_setsid				128
+#define __NR_getsid				129
+#define __NR_prctl				130
+#define __NR_personality			131
+#define __NR_getpriority			132
+#define __NR_setpriority			133
+#define __NR_setitimer				134
+#define __NR_getitimer				135
+#define __NR_setuid				136
+#define __NR_getuid				137
+#define __NR_setgid				138
+#define __NR_getgid				139
+#define __NR_geteuid				140
+#define __NR_getegid				141
+#define __NR_setreuid				142
+#define __NR_setregid				143
+#define __NR_setresuid				144
+#define __NR_getresuid				145
+#define __NR_setresgid				146
+#define __NR_getresgid				147
+#define __NR_setpgid				148
+#define __NR_getpgid				149
+#define __NR_getppid				150
+#define __NR_getpgrp				151
+#define __NR_reserved152			152	/* set_thread_area */
+#define __NR_reserved153			153	/* get_thread_area */
+#define __NR_times				154
+#define __NR_acct				155
+#define __NR_sched_setaffinity			156
+#define __NR_sched_getaffinity			157
+#define __NR_capget				158
+#define __NR_capset				159
+#define __NR_ptrace				160
+#define __NR_semtimedop				161
+#define __NR_semget				162
+#define __NR_semop				163
+#define __NR_semctl				164
+#define __NR_available165			165
+#define __NR_msgget				166
+#define __NR_msgsnd				167
+#define __NR_msgrcv				168
+#define __NR_msgctl				169
+#define __NR_available170			170
+#define __NR_umount2				171
+#define __NR_mount				172
+#define __NR_swapon				173
+#define __NR_chroot				174
+#define __NR_pivot_root				175
+#define __NR_umount				176
+#define __NR_swapoff				177
+#define __NR_sync				178
+#define __NR_syncfs				179
+#define __NR_setfsuid				180
+#define __NR_setfsgid				181
+#define __NR_sysfs				182
+#define __NR_ustat				183
+#define __NR_statfs				184
+#define __NR_fstatfs				185
+#define __NR_statfs64				186
+#define __NR_fstatfs64				187
+#define __NR_setrlimit				188
+#define __NR_getrlimit				189
+#define __NR_getrusage				190
+#define __NR_futex				191
+#define __NR_gettimeofday			192
+#define __NR_settimeofday			193
+#define __NR_adjtimex				194
+#define __NR_nanosleep				195
+#define __NR_getgroups				196
+#define __NR_setgroups				197
+#define __NR_sethostname			198
+#define __NR_setdomainname			199
+#define __NR_syslog				200
+#define __NR_vhangup				201
+#define __NR_uselib				202
+#define __NR_reboot				203
+#define __NR_quotactl				204
+#define __NR_nfsservctl				205
+#define __NR__sysctl				206
+#define __NR_bdflush				207
+#define __NR_uname				208
+#define __NR_sysinfo				209
+#define __NR_init_module			210
+#define __NR_delete_module			211
+#define __NR_sched_setparam			212
+#define __NR_sched_getparam			213
+#define __NR_sched_setscheduler			214
+#define __NR_sched_getscheduler			215
+#define __NR_sched_get_priority_max		216
+#define __NR_sched_get_priority_min		217
+#define __NR_sched_rr_get_interval		218
+#define __NR_sched_yield			219
+#define __NR_available222			222
+#define __NR_restart_syscall			223
+#define __NR_sigaltstack			224
+#define __NR_rt_sigreturn			225
+#define __NR_rt_sigaction			226
+#define __NR_rt_sigprocmask			227
+#define __NR_rt_sigpending			228
+#define __NR_rt_sigtimedwait			229
+#define __NR_rt_sigqueueinfo			230
+#define __NR_rt_sigsuspend			231
+#define __NR_mq_open				232
+#define __NR_mq_unlink				233
+#define __NR_mq_timedsend			234
+#define __NR_mq_timedreceive			235
+#define __NR_mq_notify				236
+#define __NR_mq_getsetattr			237
+#define __NR_available238			238
+#define __NR_io_setup				239
+#define __NR_io_destroy				240
+#define __NR_io_submit				241
+#define __NR_io_getevents			242
+#define __NR_io_cancel				243
+#define __NR_clock_settime			244
+#define __NR_clock_gettime			245
+#define __NR_clock_getres			246
+#define __NR_clock_nanosleep			247
+#define __NR_timer_create			248
+#define __NR_timer_delete			249
+#define __NR_timer_settime			250
+#define __NR_timer_gettime			251
+#define __NR_timer_getoverrun			252
+#define __NR_reserved253			253
+#define __NR_lookup_dcookie			254
+#define __NR_available255			255
+#define __NR_add_key				256
+#define __NR_request_key			257
+#define __NR_keyctl				258
+#define __NR_available259			259
+#define __NR_readahead				260
+#define __NR_remap_file_pages			261
+#define __NR_migrate_pages			262
+#define __NR_mbind				263
+#define __NR_get_mempolicy			264
+#define __NR_set_mempolicy			265
+#define __NR_unshare				266
+#define __NR_move_pages				267
+#define __NR_splice				268
+#define __NR_tee				269
+#define __NR_vmsplice				270
+#define __NR_available271			271
+#define __NR_pselect6				272
+#define __NR_ppoll				273
+#define __NR_epoll_pwait			274
+#define __NR_epoll_create1			275
+#define __NR_inotify_init			276
+#define __NR_inotify_add_watch			277
+#define __NR_inotify_rm_watch			278
+#define __NR_inotify_init1			279
+#define __NR_getcpu				280
+#define __NR_kexec_load				281
+#define __NR_ioprio_set				282
+#define __NR_ioprio_get				283
+#define __NR_set_robust_list			284
+#define __NR_get_robust_list			285
+#define __NR_available286			286
+#define __NR_available287			287
+#define __NR_openat				288
+#define __NR_mkdirat				289
+#define __NR_mknodat				290
+#define __NR_unlinkat				291
+#define __NR_renameat				292
+#define __NR_linkat				293
+#define __NR_symlinkat				294
+#define __NR_readlinkat				295
+#define __NR_utimensat				296
+#define __NR_fchownat				297
+#define __NR_futimesat				298
+#define __NR_fstatat64				299
+#define __NR_fchmodat				300
+#define __NR_faccessat				301
+#define __NR_available302			302
+#define __NR_available303			303
+#define __NR_signalfd				304
+#define __NR_eventfd				306
+#define __NR_recvmmsg				307
+#define __NR_setns				308
+#define __NR_signalfd4				309
+#define __NR_dup3				310
+#define __NR_pipe2				311
+#define __NR_timerfd_create			312
+#define __NR_timerfd_settime			313
+#define __NR_timerfd_gettime			314
+#define __NR_available315			315
+#define __NR_eventfd2				316
+#define __NR_preadv				317
+#define __NR_pwritev				318
+#define __NR_available319			319
+#define __NR_fanotify_init			320
+#define __NR_fanotify_mark			321
+#define __NR_process_vm_readv			322
+#define __NR_process_vm_writev			323
+#define __NR_name_to_handle_at			324
+#define __NR_open_by_handle_at			325
+#define __NR_sync_file_range2			326
+#define __NR_perf_event_open			327
+#define __NR_rt_tgsigqueueinfo			328
+#define __NR_clock_adjtime			329
+#define __NR_prlimit64				330
+#define __NR_kcmp				331
+#define __NR_finit_module			332
+#define __NR_accept4				333
+#define __NR_sched_setattr			334
+#define __NR_sched_getattr			335
+#define __NR_renameat2				336
+#define __NR_seccomp				337
+#define __NR_getrandom				338
+#define __NR_memfd_create			339
+#define __NR_bpf				340
+#define __NR_execveat				341
+#define __NR_userfaultfd			342
+#define __NR_membarrier				343
+#define __NR_mlock2				344
+#define __NR_copy_file_range			345
+#define __NR_preadv2				346
+#define __NR_pwritev2				347
+#define __NR_pkey_mprotect			348
+#define __NR_pkey_alloc				349
+#define __NR_pkey_free				350
+#define __NR_statx				351
+#define __NR_rseq				352
+#define __NR_clock_gettime64			403
+#define __NR_clock_settime64			404
+#define __NR_clock_adjtime64			405
+#define __NR_clock_getres_time64		406
+#define __NR_clock_nanosleep_time64		407
+#define __NR_timer_gettime64			408
+#define __NR_timer_settime64			409
+#define __NR_timerfd_gettime64			410
+#define __NR_timerfd_settime64			411
+#define __NR_utimensat_time64			412
+#define __NR_pselect6_time64			413
+#define __NR_ppoll_time64			414
+#define __NR_io_pgetevents_time64		416
+#define __NR_recvmmsg_time64			417
+#define __NR_mq_timedsend_time64		418
+#define __NR_mq_timedreceive_time64		419
+#define __NR_semtimedop_time64			420
+#define __NR_rt_sigtimedwait_time64		421
+#define __NR_futex_time64			422
+#define __NR_sched_rr_get_interval_time64	423
+#define __NR_pidfd_send_signal			424
+#define __NR_io_uring_setup			425
+#define __NR_io_uring_enter			426
+#define __NR_io_uring_register			427
+#define __NR_open_tree				428
+#define __NR_move_mount				429
+#define __NR_fsopen				430
+#define __NR_fsconfig				431
+#define __NR_fsmount				432
+#define __NR_fspick				433
+#define __NR_pidfd_open				434
+#define __NR_clone3				435
+#define __NR_close_range			436
+#define __NR_openat2				437
+#define __NR_pidfd_getfd			438
+#define __NR_faccessat2				439
+#define __NR_process_madvise			440
+#define __NR_epoll_pwait2			441
+#define __NR_mount_setattr			442
+#define __NR_quotactl_fd			443
+#define __NR_landlock_create_ruleset		444
+#define __NR_landlock_add_rule			445
+#define __NR_landlock_restrict_self		446
+#define __NR_process_mrelease			448
+#define __NR_futex_waitv			449
+#define __NR_set_mempolicy_home_node		450
+#define __NR_cachestat				451
+#define __NR_fchmodat2				452
+#define __NR_map_shadow_stack			453
+#define __NR_futex_wake				454
+#define __NR_futex_wait				455
+#define __NR_futex_requeue			456
+#define __NR_statmount				457
+#define __NR_listmount				458
+#define __NR_lsm_get_self_attr			459
+#define __NR_lsm_set_self_attr			460
+#define __NR_lsm_list_modules			461
diff --git a/arch/xtensa/bits/user.h b/arch/xtensa/bits/user.h
new file mode 100644
index 000000000000..8ac7526f19e0
--- /dev/null
+++ b/arch/xtensa/bits/user.h
@@ -0,0 +1,4 @@
+#define ELF_NGREG 128
+#define ELF_NFPREG 18
+typedef unsigned long elf_greg_t, elf_gregset_t[ELF_NGREG];
+typedef unsigned int elf_fpreg_t, elf_fpregset_t[ELF_NFPREG];
diff --git a/arch/xtensa/crt_arch.h b/arch/xtensa/crt_arch.h
new file mode 100644
index 000000000000..ac9b6a070be5
--- /dev/null
+++ b/arch/xtensa/crt_arch.h
@@ -0,0 +1,47 @@
+#ifdef __FDPIC__
+
+__asm__(
+".text \n"
+".global " START " \n"
+START ": \n"
+"	.begin	no-transform\n"
+"	call0	1f\n"
+"2:\n"
+"	.end	no-transform\n"
+"	.align	4\n"
+"	.literal_position\n"
+"1:\n"
+"	movi	a15, 2b\n"
+"	sub	a15, a0, a15\n"
+
+"	mov	a12, a4\n"
+"	mov	a13, a5\n"
+"	mov	a14, a6\n"
+#ifndef SHARED
+"	mov	a2, a4\n"
+"	movi	a3, __ROFIXUP_LIST__\n"
+"	add	a3, a3, a15\n"
+"	movi	a4, __ROFIXUP_END__\n"
+"	add	a4, a4, a15\n"
+"	movi	a0, __fdpic_fixup\n"
+"	add	a0, a0, a15\n"
+"	callx0	a0\n"
+"	mov	a11, a2\n"
+#endif
+"	addi	a7, a1, -8\n"
+"	s32i	a12, a7, 0\n"
+"	s32i	a13, a7, 4\n"
+"	mov	a2, a1\n"
+"	mov	a3, a14\n"
+"	movi	a4, -16\n"
+"	and	a1, a7, a4\n"
+"	movi	a0, "START"_c\n"
+"	add	a0, a0, a15\n"
+"	callx0	a0\n"
+);
+
+#ifndef SHARED
+#include "fdpic_crt.h"
+#endif
+
+#endif
diff --git a/arch/xtensa/kstat.h b/arch/xtensa/kstat.h
new file mode 100644
index 000000000000..9aeaf7e37296
--- /dev/null
+++ b/arch/xtensa/kstat.h
@@ -0,0 +1,18 @@
+struct kstat {
+	dev_t st_dev;
+	ino_t st_ino;
+	mode_t st_mode;
+	nlink_t st_nlink;
+	uid_t st_uid;
+	gid_t st_gid;
+	dev_t st_rdev;
+	off_t st_size;
+	blksize_t st_blksize;
+	blkcnt_t st_blocks;
+	long st_atime_sec;
+	long st_atime_nsec;
+	long st_mtime_sec;
+	long st_mtime_nsec;
+	long st_ctime_sec;
+	long st_ctime_nsec;
+};
diff --git a/arch/xtensa/pthread_arch.h b/arch/xtensa/pthread_arch.h
new file mode 100644
index 000000000000..a4bdd02863d6
--- /dev/null
+++ b/arch/xtensa/pthread_arch.h
@@ -0,0 +1,11 @@
+static inline uintptr_t __get_tp()
+{
+	uintptr_t tp;
+	__asm__ __volatile__ ("rur.threadptr %0" : "=a" (tp));
+	return tp;
+}
+
+#define TLS_ABOVE_TP
+#define GAP_ABOVE_TP 8
+
+#define MC_PC sc_pc
diff --git a/arch/xtensa/reloc.h b/arch/xtensa/reloc.h
new file mode 100644
index 000000000000..cd7a455a2d9c
--- /dev/null
+++ b/arch/xtensa/reloc.h
@@ -0,0 +1,32 @@
+#if __FDPIC__
+#define ABI_SUFFIX "-fdpic"
+#else
+#define ABI_SUFFIX ""
+#endif
+
+#define LDSO_ARCH "xtensa" ABI_SUFFIX
+
+#define TPOFF_K 0
+
+#define REL_PLT         R_XTENSA_JMP_SLOT
+#define REL_GOT         R_XTENSA_GLOB_DAT
+
+#if __FDPIC__
+#define REL_SYMBOLIC	R_XTENSA_SYM32
+#define REL_TPOFF	R_XTENSA_TLS_TPOFF
+#define REL_TLSDESC	R_XTENSA_TLSDESC
+#define REL_FUNCDESC	R_XTENSA_FUNCDESC
+#define REL_FUNCDESC_VAL R_XTENSA_FUNCDESC_VALUE
+
+#define DL_FDPIC 1
+#define DL_NOMMU_SUPPORT 1
+
+#define CRTJMP(pc,sp) do { \
+	register size_t a4 __asm__("a4") = ((size_t *)(sp))[-2]; \
+	__asm__ __volatile__( "mov a1, %1 ; jx %0" \
+	: : "r"(pc), "r"(sp), "r"(a4) : "memory" ); } while(0)
+
+#define GETFUNCSYM(fp, sym, got) __asm__ ( \
+	"movi %0, " #sym "@GOTOFFFUNCDESC ; add %0, %0, %1" \
+	: "=&a"(*fp) : "a"(got) : "memory" )
+#endif
diff --git a/arch/xtensa/syscall_arch.h b/arch/xtensa/syscall_arch.h
new file mode 100644
index 000000000000..63ee4e962556
--- /dev/null
+++ b/arch/xtensa/syscall_arch.h
@@ -0,0 +1,104 @@
+#define __SYSCALL_LL_E(x) \
+((union { long long ll; long l[2]; }){ .ll = x }).l[0], \
+((union { long long ll; long l[2]; }){ .ll = x }).l[1]
+#define __SYSCALL_LL_O(x) 0, __SYSCALL_LL_E((x))
+
+static inline long __syscall0(long n)
+{
+	register long a2 __asm__("a2") = n;
+
+	__asm__ __volatile__ ("syscall"
+			      : "+&a"(a2)
+			      :
+			      : "memory");
+	return a2;
+}
+
+static inline long __syscall1(long n, long a)
+{
+	register long a2 __asm__("a2") = n;
+	register long a6 __asm__("a6") = a;
+
+	__asm__ __volatile__ ("syscall"
+			      : "+&a"(a2)
+			      : "a"(a6)
+			      : "memory");
+	return a2;
+}
+
+static inline long __syscall2(long n, long a, long b)
+{
+	register long a2 __asm__("a2") = n;
+	register long a6 __asm__("a6") = a;
+	register long a3 __asm__("a3") = b;
+
+	__asm__ __volatile__ ("syscall"
+			      : "+&a"(a2)
+			      : "a"(a6), "a"(a3)
+			      : "memory");
+	return a2;
+}
+
+static inline long __syscall3(long n, long a, long b, long c)
+{
+	register long a2 __asm__("a2") = n;
+	register long a6 __asm__("a6") = a;
+	register long a3 __asm__("a3") = b;
+	register long a4 __asm__("a4") = c;
+
+	__asm__ __volatile__ ("syscall"
+			      : "+&a"(a2)
+			      : "a"(a6), "a"(a3), "a"(a4)
+			      : "memory");
+	return a2;
+}
+
+static inline long __syscall4(long n, long a, long b, long c, long d)
+{
+	register long a2 __asm__("a2") = n;
+	register long a6 __asm__("a6") = a;
+	register long a3 __asm__("a3") = b;
+	register long a4 __asm__("a4") = c;
+	register long a5 __asm__("a5") = d;
+
+	__asm__ __volatile__ ("syscall"
+			      : "+&a"(a2)
+			      : "a"(a6), "a"(a3), "a"(a4), "a"(a5)
+			      : "memory");
+	return a2;
+}
+
+static inline long __syscall5(long n, long a, long b, long c, long d, long e)
+{
+	register long a2 __asm__("a2") = n;
+	register long a6 __asm__("a6") = a;
+	register long a3 __asm__("a3") = b;
+	register long a4 __asm__("a4") = c;
+	register long a5 __asm__("a5") = d;
+	register long a8 __asm__("a8") = e;
+
+	__asm__ __volatile__ ("syscall"
+			      : "+&a"(a2)
+			      : "a"(a6), "a"(a3), "a"(a4), "a"(a5), "a"(a8)
+			      : "memory");
+	return a2;
+}
+
+static inline long __syscall6(long n, long a, long b, long c, long d, long e, long f)
+{
+	register long a2 __asm__("a2") = n;
+	register long a6 __asm__("a6") = a;
+	register long a3 __asm__("a3") = b;
+	register long a4 __asm__("a4") = c;
+	register long a5 __asm__("a5") = d;
+	register long a8 __asm__("a8") = e;
+	register long a9 __asm__("a9") = f;
+
+	__asm__ __volatile__ ("syscall"
+			      : "+&a"(a2)
+			      : "a"(a6), "a"(a3), "a"(a4), "a"(a5), "a"(a8), "a"(a9)
+			      : "memory");
+	return a2;
+}
+
+#define SYSCALL_FADVISE_6_ARG
diff --git a/configure b/configure
index bc9fbe48cc44..898499ce77ba 100755
--- a/configure
+++ b/configure
@@ -340,6 +340,7 @@ riscv64*) ARCH=riscv64 ;;
 riscv32*) ARCH=riscv32 ;;
 sh[1-9bel-]*|sh|superh*) ARCH=sh ;;
 s390x*) ARCH=s390x ;;
+xtensa*) ARCH=xtensa ;;
 unknown) fail "$0: unable to detect target arch; try $0 --target=..." ;;
 *) fail "$0: unknown or unsupported target \"$target\"" ;;
 esac
@@ -756,6 +757,13 @@ SUBARCH=${SUBARCH}-fdpic
 fi
 fi
 
+if test "$ARCH" = "xtensa" ; then
+if trycppif __XTENSA_WINDOWED_ABI__ "$t" ; then
+fail "$0: error: compiler uses unsupported ABI by default"
+fi
+trycppif __FDPIC__ "$t" && SUBARCH=${SUBARCH}-fdpic
+fi
+
 test "$SUBARCH" \
 && printf "configured for %s variant: %s\n" "$ARCH" "$ARCH$SUBARCH"
 
diff --git a/crt/xtensa/crti.S b/crt/xtensa/crti.S
new file mode 100644
index 000000000000..20d910820288
--- /dev/null
+++ b/crt/xtensa/crti.S
@@ -0,0 +1,23 @@
+.section .init
+.global  _init
+.type    _init, @function
+.align	4
+_init:
+	addi	sp, sp, -16
+	s32i	a0, sp, 0
+#ifdef __FDPIC__
+	s32i	a12, sp, 4
+	mov	a12, a11
+#endif
+
+.section .fini
+.global  _fini
+.type    _fini, @function
+.align	4
+_fini:
+	addi	sp, sp, -16
+	s32i	a0, sp, 0
+#ifdef __FDPIC__
+	s32i	a12, sp, 4
+	mov	a12, a11
+#endif
diff --git a/crt/xtensa/crtn.S b/crt/xtensa/crtn.S
new file mode 100644
index 000000000000..656edaa7f146
--- /dev/null
+++ b/crt/xtensa/crtn.S
@@ -0,0 +1,15 @@
+.section .init
+#ifdef __FDPIC__
+	l32i	a12, sp, 4
+#endif
+	l32i	a0, sp, 0
+	addi	sp, sp, 16
+	ret
+
+.section .fini
+#ifdef __FDPIC__
+	l32i	a12, sp, 4
+#endif
+	l32i	a0, sp, 0
+	addi	sp, sp, 16
+	ret
diff --git a/include/elf.h b/include/elf.h
index 3d5e13e4b6e5..fdd1e3163546 100644
--- a/include/elf.h
+++ b/include/elf.h
@@ -3406,6 +3406,80 @@ enum
 #define R_LARCH_32_PCREL                    99
 #define R_LARCH_RELAX                       100
 
+#define R_XTENSA_NONE		0
+#define R_XTENSA_32		1
+#define R_XTENSA_RTLD		2
+#define R_XTENSA_GLOB_DAT	3
+#define R_XTENSA_JMP_SLOT	4
+#define R_XTENSA_RELATIVE	5
+#define R_XTENSA_PLT		6
+#define R_XTENSA_OP0		8
+#define R_XTENSA_OP1		9
+#define R_XTENSA_OP2		10
+#define R_XTENSA_ASM_EXPAND	11
+#define R_XTENSA_ASM_SIMPLIFY	12
+#define R_XTENSA_32_PCREL	14
+#define R_XTENSA_GNU_VTINHERIT	15
+#define R_XTENSA_GNU_VTENTRY	16
+#define R_XTENSA_DIFF8		17
+#define R_XTENSA_DIFF16		18
+#define R_XTENSA_DIFF32		19
+#define R_XTENSA_SLOT0_OP	20
+#define R_XTENSA_SLOT1_OP	21
+#define R_XTENSA_SLOT2_OP	22
+#define R_XTENSA_SLOT3_OP	23
+#define R_XTENSA_SLOT4_OP	24
+#define R_XTENSA_SLOT5_OP	25
+#define R_XTENSA_SLOT6_OP	26
+#define R_XTENSA_SLOT7_OP	27
+#define R_XTENSA_SLOT8_OP	28
+#define R_XTENSA_SLOT9_OP	29
+#define R_XTENSA_SLOT10_OP	30
+#define R_XTENSA_SLOT11_OP	31
+#define R_XTENSA_SLOT12_OP	32
+#define R_XTENSA_SLOT13_OP	33
+#define R_XTENSA_SLOT14_OP	34
+#define R_XTENSA_SLOT0_ALT	35
+#define R_XTENSA_SLOT1_ALT	36
+#define R_XTENSA_SLOT2_ALT	37
+#define R_XTENSA_SLOT3_ALT	38
+#define R_XTENSA_SLOT4_ALT	39
+#define R_XTENSA_SLOT5_ALT	40
+#define R_XTENSA_SLOT6_ALT	41
+#define R_XTENSA_SLOT7_ALT	42
+#define R_XTENSA_SLOT8_ALT	43
+#define R_XTENSA_SLOT9_ALT	44
+#define R_XTENSA_SLOT10_ALT	45
+#define R_XTENSA_SLOT11_ALT	46
+#define R_XTENSA_SLOT12_ALT	47
+#define R_XTENSA_SLOT13_ALT	48
+#define R_XTENSA_SLOT14_ALT	49
+#define R_XTENSA_TLSDESC_FN	50
+#define R_XTENSA_TLSDESC_ARG	51
+#define R_XTENSA_TLS_DTPOFF	52
+#define R_XTENSA_TLS_TPOFF	53
+#define R_XTENSA_TLS_FUNC	54
+#define R_XTENSA_TLS_ARG	55
+#define R_XTENSA_TLS_CALL	56
+#define R_XTENSA_PDIFF8		57
+#define R_XTENSA_PDIFF16	58
+#define R_XTENSA_PDIFF32	59
+#define R_XTENSA_NDIFF8		60
+#define R_XTENSA_NDIFF16	61
+#define R_XTENSA_NDIFF32	62
+#define R_XTENSA_SYM32		63
+#define R_XTENSA_GOT		64
+#define R_XTENSA_GOTOFF		65
+#define R_XTENSA_GOTFUNCDESC	66
+#define R_XTENSA_GOTOFFFUNCDESC	67
+#define R_XTENSA_FUNCDESC	68
+#define R_XTENSA_FUNCDESC_VALUE	69
+#define R_XTENSA_TLS_GOTTPOFF	70
+#define R_XTENSA_GOTTLSDESC	71
+#define R_XTENSA_TLSDESC	72
+
+#define R_XTENSA_NUM		77
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/src/internal/xtensa/syscall.s b/src/internal/xtensa/syscall.s
new file mode 100644
index 000000000000..3112bc3890bc
--- /dev/null
+++ b/src/internal/xtensa/syscall.s
@@ -0,0 +1,14 @@
+.global __syscall
+.hidden __syscall
+.type   __syscall,@function
+.align 4
+__syscall:
+	mov	a8, a3
+	mov	a3, a4
+	mov	a4, a5
+	mov	a5, a6
+	mov	a6, a8
+	mov	a8, a7
+	l32i	a9, a1, 0
+	syscall
+	ret
diff --git a/src/ldso/xtensa/dlsym.s b/src/ldso/xtensa/dlsym.s
new file mode 100644
index 000000000000..4b7a975f3b2e
--- /dev/null
+++ b/src/ldso/xtensa/dlsym.s
@@ -0,0 +1,7 @@
+.global dlsym
+.hidden __dlsym
+.type dlsym,@function
+.align	4
+dlsym:
+	mov	a4, a0
+	j	__dlsym
diff --git a/src/ldso/xtensa/dlsym_time64.S b/src/ldso/xtensa/dlsym_time64.S
new file mode 100644
index 000000000000..bb2e70408f0e
--- /dev/null
+++ b/src/ldso/xtensa/dlsym_time64.S
@@ -0,0 +1,3 @@
+#define __dlsym __dlsym_redir_time64
+#define dlsym __dlsym_time64
+#include "dlsym.s"
diff --git a/src/ldso/xtensa/tlsdesc.s b/src/ldso/xtensa/tlsdesc.s
new file mode 100644
index 000000000000..4dcb78c9e92f
--- /dev/null
+++ b/src/ldso/xtensa/tlsdesc.s
@@ -0,0 +1,25 @@
+.global __tlsdesc_static
+.hidden __tlsdesc_static
+.type __tlsdesc_static,@function
+.align 4
+__tlsdesc_static:
+	l32i		a2, a2, 4
+	rur.threadptr	a3
+	add		a2, a2, a3
+	ret
+
+.global __tlsdesc_dynamic
+.hidden __tlsdesc_dynamic
+.type __tlsdesc_dynamic,@function
+.align 4
+__tlsdesc_dynamic:
+	l32i		a2, a2, 4	# a2 = &{modidx, off}
+	rur.threadptr	a3
+	addi		a3, a3, -4
+	l32i		a3, a3, 0	# a3 = dtv
+	l32i		a4, a2, 0	# a4 = modidx
+	addx4		a3, a4, a3
+	l32i		a3, a3, 0	# a3 = dtv[modidx]
+	l32i		a2, a2, 4
+	add		a2, a2, a3	# a2 = dtv[modidx] + off
+	ret
diff --git a/src/process/xtensa/vfork.s b/src/process/xtensa/vfork.s
new file mode 100644
index 000000000000..f62dd0fb5464
--- /dev/null
+++ b/src/process/xtensa/vfork.s
@@ -0,0 +1,15 @@
+.global vfork
+.type vfork,@function
+.align	4
+.literal_position
+vfork:
+	movi	a2, 116 # __NR_clone
+	movi	a3, 0
+	movi	a6, 0x4111 # CLONE_VM | CLONE_VFORK | SIGCHLD
+	syscall
+
+.hidden __syscall_ret
+	movi	a9, __syscall_ret@GOT
+	add	a9, a9, a11
+	l32i	a9, a9, 0
+	jx	a9
diff --git a/src/setjmp/xtensa/longjmp.s b/src/setjmp/xtensa/longjmp.s
new file mode 100644
index 000000000000..c650126c5354
--- /dev/null
+++ b/src/setjmp/xtensa/longjmp.s
@@ -0,0 +1,18 @@
+.global _longjmp
+.global longjmp
+.type _longjmp,@function
+.type longjmp,@function
+.align 4
+_longjmp:
+longjmp:
+	l32i	a0, a2, 0
+	l32i	a1, a2, 4
+	l32i	a12, a2, 8
+	l32i	a13, a2, 12
+	l32i	a14, a2, 16
+	l32i	a15, a2, 20
+
+	movi	a2, 1
+	movnez	a2, a3, a3
+
+	ret
diff --git a/src/setjmp/xtensa/setjmp.s b/src/setjmp/xtensa/setjmp.s
new file mode 100644
index 000000000000..4d229a86f83a
--- /dev/null
+++ b/src/setjmp/xtensa/setjmp.s
@@ -0,0 +1,21 @@
+.global ___setjmp
+.hidden ___setjmp
+.global __setjmp
+.global _setjmp
+.global setjmp
+.type __setjmp,@function
+.type _setjmp,@function
+.type setjmp,@function
+.align 4
+___setjmp:
+__setjmp:
+_setjmp:
+setjmp:
+	s32i	a0, a2, 0
+	s32i	a1, a2, 4
+	s32i	a12, a2, 8
+	s32i	a13, a2, 12
+	s32i	a14, a2, 16
+	s32i	a15, a2, 20
+	movi	a2, 0
+	ret
diff --git a/src/signal/xtensa/restore.s b/src/signal/xtensa/restore.s
new file mode 100644
index 000000000000..e03e0fb798fb
--- /dev/null
+++ b/src/signal/xtensa/restore.s
@@ -0,0 +1,10 @@
+.global __restore
+.global __restore_rt
+.type __restore,@function
+.type __restore_rt,@function
+.space 1
+.align 4
+__restore:
+__restore_rt:
+	movi	a2, 225 # SYS_rt_sigreturn
+	syscall
diff --git a/src/signal/xtensa/sigsetjmp.s b/src/signal/xtensa/sigsetjmp.s
new file mode 100644
index 000000000000..796564134886
--- /dev/null
+++ b/src/signal/xtensa/sigsetjmp.s
@@ -0,0 +1,22 @@
+.global sigsetjmp
+.global __sigsetjmp
+.type sigsetjmp,@function
+.type __sigsetjmp,@function
+.align 4
+sigsetjmp:
+__sigsetjmp:
+	bnez	a3, 1f
+.hidden ___setjmp
+	j	___setjmp
+1:
+	s32i	a0, a2, 24
+	s32i	a12, a2, 36
+	mov	a12, a2
+	call0	___setjmp
+	mov	a3, a2
+	mov	a2, a12
+	l32i	a12, a2, 36
+	l32i	a0, a2, 24
+
+.hidden __sigsetjmp_tail
+	j	__sigsetjmp_tail
diff --git a/src/thread/xtensa/__set_thread_area.c b/src/thread/xtensa/__set_thread_area.c
new file mode 100644
index 000000000000..56be098215c2
--- /dev/null
+++ b/src/thread/xtensa/__set_thread_area.c
@@ -0,0 +1,9 @@
+#include "pthread_impl.h"
+#include "libc.h"
+#include <elf.h>
+
+int __set_thread_area(void *p)
+{
+	__asm__ __volatile__ ("wur.threadptr %0" :: "r"(p) : "memory");
+	return 0;
+}
diff --git a/src/thread/xtensa/__unmapself.s b/src/thread/xtensa/__unmapself.s
new file mode 100644
index 000000000000..8f007e84ec43
--- /dev/null
+++ b/src/thread/xtensa/__unmapself.s
@@ -0,0 +1,9 @@
+.global __unmapself
+.type   __unmapself,@function
+.align 4
+__unmapself:
+	mov	a6, a2
+	movi	a2, 81 # SYS_munmap
+	syscall
+	movi	a2, 118 # SYS_exit
+	syscall
diff --git a/src/thread/xtensa/clone.S b/src/thread/xtensa/clone.S
new file mode 100644
index 000000000000..f7400f5c7566
--- /dev/null
+++ b/src/thread/xtensa/clone.S
@@ -0,0 +1,42 @@
+# __clone(func, stack, flags, arg, ptid, tls, ctid)
+#         a2,   a3,    a4,    a5,  a6,   a7,  [sp]
+
+# syscall(SYS_clone, flags, stack, ptid, tls, ctid)
+#         a2,        a6,    a3,    a4,   a5,  a8
+
+.global __clone
+.type   __clone,@function
+.align 4
+__clone:
+	# align stack and save func,arg
+	srli	a3, a3, 4
+	slli	a3, a3, 4
+	addi	a3, a3, -16
+	s32i	a2, a3, 0
+	s32i	a5, a3, 4
+
+	# syscall
+	mov	a2, a4
+	mov	a4, a6
+	mov	a6, a2
+	mov	a5, a7
+	l32i	a8, a1, 0
+	movi	a2, 116 # SYS_clone
+	syscall
+
+	beqz	a2, 1f
+	# parent
+	ret
+
+	# child
+1:
+	l32i	a0, a1, 0
+	l32i	a2, a1, 4
+#ifdef __FDPIC__
+	l32i	a11, a0, 4
+	l32i	a0, a0, 0
+#endif
+	callx0	a0
+	mov	a6, a2
+	movi	a2, 118 # SYS_exit
+	syscall
diff --git a/src/thread/xtensa/syscall_cp.s b/src/thread/xtensa/syscall_cp.s
new file mode 100644
index 000000000000..55575e359b87
--- /dev/null
+++ b/src/thread/xtensa/syscall_cp.s
@@ -0,0 +1,34 @@
+# __syscall_cp_asm(&self->cancel, nr, u, v, w, x, y, z)
+#                  a2             a3  a4 a5 a6 a7 [sp] [sp+4]
+
+# syscall(nr, u, v, w, x, y, z)
+#         a2  a6 a3 a4 a5 a8 a9
+
+.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
+.type __syscall_cp_asm,@function
+.align 4
+__syscall_cp_asm:
+__cp_begin:
+	l32i	a2, a2, 0
+	bnez	a2, __cp_cancel
+	mov	a2, a4
+	mov	a4, a6
+	mov	a6, a2
+	mov	a2, a3
+	mov	a3, a5
+	mov	a5, a7
+	l32i	a8, a1, 0
+	l32i	a9, a1, 4
+	syscall
+__cp_end:
+	ret
+__cp_cancel:
+	j	__cancel
-- 
2.39.2

Powered by blists - more mailing lists

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