diff options
Diffstat (limited to 'libc/sysdeps/linux/xtensa')
-rw-r--r-- | libc/sysdeps/linux/xtensa/Makefile.arch | 3 | ||||
-rw-r--r-- | libc/sysdeps/linux/xtensa/__start_context.S | 100 | ||||
-rw-r--r-- | libc/sysdeps/linux/xtensa/__syscall_error.c | 4 | ||||
-rw-r--r-- | libc/sysdeps/linux/xtensa/bits/atomic.h | 177 | ||||
-rw-r--r-- | libc/sysdeps/linux/xtensa/bits/fcntl.h | 7 | ||||
-rw-r--r-- | libc/sysdeps/linux/xtensa/bits/ipc.h | 4 | ||||
-rw-r--r-- | libc/sysdeps/linux/xtensa/bits/kernel_stat.h | 6 | ||||
-rw-r--r-- | libc/sysdeps/linux/xtensa/bits/msq.h | 16 | ||||
-rw-r--r-- | libc/sysdeps/linux/xtensa/bits/shm.h | 24 | ||||
-rw-r--r-- | libc/sysdeps/linux/xtensa/bits/stat.h | 8 | ||||
-rw-r--r-- | libc/sysdeps/linux/xtensa/bits/xtensa-config.h | 6 | ||||
-rw-r--r-- | libc/sysdeps/linux/xtensa/crt1.S | 27 | ||||
-rw-r--r-- | libc/sysdeps/linux/xtensa/getcontext.S | 99 | ||||
-rw-r--r-- | libc/sysdeps/linux/xtensa/makecontext.c | 179 | ||||
-rw-r--r-- | libc/sysdeps/linux/xtensa/setcontext.S | 116 | ||||
-rw-r--r-- | libc/sysdeps/linux/xtensa/swapcontext.S | 173 | ||||
-rw-r--r-- | libc/sysdeps/linux/xtensa/sysdep.h | 7 | ||||
-rw-r--r-- | libc/sysdeps/linux/xtensa/ucontext_i.sym | 15 |
18 files changed, 911 insertions, 60 deletions
diff --git a/libc/sysdeps/linux/xtensa/Makefile.arch b/libc/sysdeps/linux/xtensa/Makefile.arch index 23cd08ee5..f3a93caaa 100644 --- a/libc/sysdeps/linux/xtensa/Makefile.arch +++ b/libc/sysdeps/linux/xtensa/Makefile.arch @@ -10,3 +10,6 @@ SSRC-y := bsd-_setjmp.S bsd-setjmp.S setjmp.S clone.S \ sigrestorer.S syscall.S mmap.S windowspill.S __longjmp.S vfork.S CSRC-$(if $(UCLIBC_HAS_THREADS_NATIVE),,y) += fork.c + +CSRC-$(UCLIBC_HAS_CONTEXT_FUNCS) += makecontext.c +SSRC-$(UCLIBC_HAS_CONTEXT_FUNCS) += setcontext.S getcontext.S swapcontext.S __start_context.S diff --git a/libc/sysdeps/linux/xtensa/__start_context.S b/libc/sysdeps/linux/xtensa/__start_context.S new file mode 100644 index 000000000..a30d7b618 --- /dev/null +++ b/libc/sysdeps/linux/xtensa/__start_context.S @@ -0,0 +1,100 @@ +/* Copyright (C) 2018 - 2022 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <sysdep.h> + +#if defined(__XTENSA_CALL0_ABI__) +/* + * There's no entry instruction, makecontext sets up ucontext_t as if + * getcontext was called above and is about to return here. + * Registers on entry to this function: + * a12: func to call + * a13: ucp->uc_link, next context to activate if func returns + * a14: func argc + */ + .literal_position + +ENTRY_PREFIX(__start_context) + + beqz a14, 1f + + /* load func arguments 0..1 from stack and free that space */ + l32i a2, a1, 8 + l32i a3, a1, 12 + addi a1, a1, 16 + bltui a14, 3, 1f + + /* load func arguments 2..5 from stack and free that space */ + l32i a4, a1, 0 + l32i a5, a1, 4 + l32i a6, a1, 8 + l32i a7, a1, 12 + addi a1, a1, 16 + /* func arguments 6..argc - 1 are now at the top of the stack */ +1: + callx0 a12 + beqz a13, 1f + mov a2, a13 + movi a4, JUMPTARGET (setcontext) + callx0 a4 +1: + movi a4, JUMPTARGET (_exit) + movi a2, 0 + callx0 a4 + ill +END(__start_context) +#elif defined(__XTENSA_WINDOWED_ABI__) +/* + * There's no entry instruction, makecontext sets up ucontext_t as if + * getcontext was called above and is about to return here. + * Registers on entry to this function: + * a2: func to call + * a3: ucp->uc_link, next context to activate if func returns + * a4: func argc + * a5..a7: func arguments 0..2 + */ + .literal_position + +ENTRY_PREFIX(__start_context) + + mov a10, a5 + mov a11, a6 + mov a12, a7 + bltui a4, 4, 1f + + /* load func arguments 3..5 from stack and free that space */ + l32i a13, a1, 4 + l32i a14, a1, 8 + l32i a15, a1, 12 + addi a5, a1, 16 + movsp a1, a5 + /* func arguments 6..argc - 1 are now at the top of the stack */ +1: + callx8 a2 + beqz a3, 1f + mov a6, a3 + movi a4, JUMPTARGET (setcontext) + callx4 a4 +1: + movi a4, JUMPTARGET (_exit) + movi a6, 0 + callx4 a4 + ill +END(__start_context) +#else +#error Unsupported Xtensa ABI +#endif diff --git a/libc/sysdeps/linux/xtensa/__syscall_error.c b/libc/sysdeps/linux/xtensa/__syscall_error.c index 2b642e816..c682aae49 100644 --- a/libc/sysdeps/linux/xtensa/__syscall_error.c +++ b/libc/sysdeps/linux/xtensa/__syscall_error.c @@ -10,8 +10,8 @@ /* This routine is jumped to by all the syscall handlers, to stash * an error number into errno. */ -int __syscall_error(int err_no) attribute_hidden; -int __syscall_error(int err_no) +long __syscall_error(int err_no) attribute_hidden; +long __syscall_error(int err_no) { __set_errno(-err_no); return -1; diff --git a/libc/sysdeps/linux/xtensa/bits/atomic.h b/libc/sysdeps/linux/xtensa/bits/atomic.h index b2be547f0..18b809998 100644 --- a/libc/sysdeps/linux/xtensa/bits/atomic.h +++ b/libc/sysdeps/linux/xtensa/bits/atomic.h @@ -18,6 +18,7 @@ #ifndef _BITS_ATOMIC_H #define _BITS_ATOMIC_H 1 +#include <bits/xtensa-config.h> #include <inttypes.h> typedef int32_t atomic32_t; @@ -50,22 +51,144 @@ typedef uintmax_t uatomic_max_t; #define __arch_compare_and_exchange_bool_16_rel(mem, newval, oldval) \ (abort (), 0) +#if XCHAL_HAVE_EXCLUSIVE + +/* Atomically store NEWVAL in *MEM if *MEM is equal to OLDVAL. + Return the old *MEM value. */ + +#define __arch_compare_and_exchange_val_32_acq(mem, newval, oldval) \ + ({__typeof__(*(mem)) __tmp, __value; \ + __asm__ __volatile__( \ + " memw \n" \ + "1: l32ex %0, %2 \n" \ + " bne %0, %4, 2f \n" \ + " mov %1, %3 \n" \ + " s32ex %1, %2 \n" \ + " getex %1 \n" \ + " beqz %1, 1b \n" \ + " memw \n" \ + "2: \n" \ + : "=&a" (__value), "=&a" (__tmp) \ + : "a" (mem), "a" (newval), "a" (oldval) \ + : "memory" ); \ + __value; \ + }) + +/* Atomically store NEWVAL in *MEM if *MEM is equal to OLDVAL. + Return zero if *MEM was changed or non-zero if no exchange happened. */ + +#define __arch_compare_and_exchange_bool_32_acq(mem, newval, oldval) \ + ({__typeof__(*(mem)) __tmp, __value; \ + __asm__ __volatile__( \ + " memw \n" \ + "1: l32ex %0, %2 \n" \ + " sub %0, %4, %0 \n" \ + " bnez %0, 2f \n" \ + " mov %1, %3 \n" \ + " s32ex %1, %2 \n" \ + " getex %1 \n" \ + " beqz %1, 1b \n" \ + " movi %0, 0 \n" \ + " memw \n" \ + "2: \n" \ + : "=&a" (__value), "=&a" (__tmp) \ + : "a" (mem), "a" (newval), "a" (oldval) \ + : "memory" ); \ + __value != 0; \ + }) + +/* Store NEWVALUE in *MEM and return the old value. */ + +#define __arch_exchange_32_acq(mem, newval) \ + ({__typeof__(*(mem)) __tmp, __value; \ + __asm__ __volatile__( \ + " memw \n" \ + "1: l32ex %0, %2 \n" \ + " mov %1, %3 \n" \ + " s32ex %1, %2 \n" \ + " getex %1 \n" \ + " beqz %1, 1b \n" \ + " memw \n" \ + : "=&a" (__value), "=&a" (__tmp) \ + : "a" (mem), "a" (newval) \ + : "memory" ); \ + __value; \ + }) + +/* Add VALUE to *MEM and return the old value of *MEM. */ + +#define __arch_atomic_exchange_and_add_32(mem, value) \ + ({__typeof__(*(mem)) __tmp, __value; \ + __asm__ __volatile__( \ + " memw \n" \ + "1: l32ex %0, %2 \n" \ + " add %1, %0, %3 \n" \ + " s32ex %1, %2 \n" \ + " getex %1 \n" \ + " beqz %1, 1b \n" \ + " memw \n" \ + : "=&a" (__value), "=&a" (__tmp) \ + : "a" (mem), "a" (value) \ + : "memory" ); \ + __value; \ + }) + +/* Subtract VALUE from *MEM and return the old value of *MEM. */ + +#define __arch_atomic_exchange_and_sub_32(mem, value) \ + ({__typeof__(*(mem)) __tmp, __value; \ + __asm__ __volatile__( \ + " memw \n" \ + "1: l32ex %0, %2 \n" \ + " sub %1, %0, %3 \n" \ + " s32ex %1, %2 \n" \ + " getex %1 \n" \ + " beqz %1, 1b \n" \ + " memw \n" \ + : "=&a" (__value), "=&a" (__tmp) \ + : "a" (mem), "a" (value) \ + : "memory" ); \ + __tmp; \ + }) + +/* Decrement *MEM if it is > 0, and return the old value. */ + +#define __arch_atomic_decrement_if_positive_32(mem) \ + ({__typeof__(*(mem)) __tmp, __value; \ + __asm__ __volatile__( \ + " memw \n" \ + "1: l32ex %0, %2 \n" \ + " blti %0, 1, 2f \n" \ + " addi %1, %0, -1 \n" \ + " s32ex %1, %2 \n" \ + " getex %1 \n" \ + " beqz %1, 1b \n" \ + " memw \n" \ + "2: \n" \ + : "=&a" (__value), "=&a" (__tmp) \ + : "a" (mem) \ + : "memory" ); \ + __value; \ + }) + +#elif XCHAL_HAVE_S32C1I + /* Atomically store NEWVAL in *MEM if *MEM is equal to OLDVAL. Return the old *MEM value. */ #define __arch_compare_and_exchange_val_32_acq(mem, newval, oldval) \ ({__typeof__(*(mem)) __tmp, __value; \ __asm__ __volatile__( \ - "1: l32i %1, %2, 0 \n" \ + "1: l32i %1, %2 \n" \ " bne %1, %4, 2f \n" \ " wsr %1, SCOMPARE1 \n" \ " mov %0, %1 \n" \ " mov %1, %3 \n" \ - " s32c1i %1, %2, 0 \n" \ + " s32c1i %1, %2 \n" \ " bne %0, %1, 1b \n" \ "2: \n" \ - : "=&a" (__value), "=&a" (__tmp) \ - : "a" (mem), "a" (newval), "a" (oldval) \ + : "=&a" (__value), "=&a" (__tmp), "+m" (*(mem)) \ + : "a" (newval), "a" (oldval) \ : "memory" ); \ __tmp; \ }) @@ -76,17 +199,17 @@ typedef uintmax_t uatomic_max_t; #define __arch_compare_and_exchange_bool_32_acq(mem, newval, oldval) \ ({__typeof__(*(mem)) __tmp, __value; \ __asm__ __volatile__( \ - "1: l32i %0, %2, 0 \n" \ + "1: l32i %0, %2 \n" \ " sub %1, %4, %0 \n" \ " bnez %1, 2f \n" \ " wsr %0, SCOMPARE1 \n" \ " mov %1, %3 \n" \ - " s32c1i %1, %2, 0 \n" \ + " s32c1i %1, %2 \n" \ " bne %0, %1, 1b \n" \ " movi %1, 0 \n" \ "2: \n" \ - : "=&a" (__value), "=&a" (__tmp) \ - : "a" (mem), "a" (newval), "a" (oldval) \ + : "=&a" (__value), "=&a" (__tmp), "+m" (*(mem)) \ + : "a" (newval), "a" (oldval) \ : "memory" ); \ __tmp != 0; \ }) @@ -96,13 +219,13 @@ typedef uintmax_t uatomic_max_t; #define __arch_exchange_32_acq(mem, newval) \ ({__typeof__(*(mem)) __tmp, __value; \ __asm__ __volatile__( \ - "1: l32i %0, %2, 0 \n" \ + "1: l32i %0, %2 \n" \ " wsr %0, SCOMPARE1 \n" \ " mov %1, %3 \n" \ - " s32c1i %1, %2, 0 \n" \ + " s32c1i %1, %2 \n" \ " bne %0, %1, 1b \n" \ - : "=&a" (__value), "=&a" (__tmp) \ - : "a" (mem), "a" (newval) \ + : "=&a" (__value), "=&a" (__tmp), "+m" (*(mem)) \ + : "a" (newval) \ : "memory" ); \ __tmp; \ }) @@ -112,13 +235,13 @@ typedef uintmax_t uatomic_max_t; #define __arch_atomic_exchange_and_add_32(mem, value) \ ({__typeof__(*(mem)) __tmp, __value; \ __asm__ __volatile__( \ - "1: l32i %0, %2, 0 \n" \ + "1: l32i %0, %2 \n" \ " wsr %0, SCOMPARE1 \n" \ " add %1, %0, %3 \n" \ - " s32c1i %1, %2, 0 \n" \ + " s32c1i %1, %2 \n" \ " bne %0, %1, 1b \n" \ - : "=&a" (__value), "=&a" (__tmp) \ - : "a" (mem), "a" (value) \ + : "=&a" (__value), "=&a" (__tmp), "+m" (*(mem)) \ + : "a" (value) \ : "memory" ); \ __tmp; \ }) @@ -128,13 +251,13 @@ typedef uintmax_t uatomic_max_t; #define __arch_atomic_exchange_and_sub_32(mem, value) \ ({__typeof__(*(mem)) __tmp, __value; \ __asm__ __volatile__( \ - "1: l32i %0, %2, 0 \n" \ + "1: l32i %0, %2 \n" \ " wsr %0, SCOMPARE1 \n" \ " sub %1, %0, %3 \n" \ - " s32c1i %1, %2, 0 \n" \ + " s32c1i %1, %2 \n" \ " bne %0, %1, 1b \n" \ - : "=&a" (__value), "=&a" (__tmp) \ - : "a" (mem), "a" (value) \ + : "=&a" (__value), "=&a" (__tmp), "+m" (*(mem)) \ + : "a" (value) \ : "memory" ); \ __tmp; \ }) @@ -144,19 +267,23 @@ typedef uintmax_t uatomic_max_t; #define __arch_atomic_decrement_if_positive_32(mem) \ ({__typeof__(*(mem)) __tmp, __value; \ __asm__ __volatile__( \ - "1: l32i %0, %2, 0 \n" \ + "1: l32i %0, %2 \n" \ " blti %0, 1, 2f \n" \ " wsr %0, SCOMPARE1 \n" \ " addi %1, %0, -1 \n" \ - " s32c1i %1, %2, 0 \n" \ + " s32c1i %1, %2 \n" \ " bne %0, %1, 1b \n" \ "2: \n" \ - : "=&a" (__value), "=&a" (__tmp) \ - : "a" (mem) \ - : "memory" ); \ + : "=&a" (__value), "=&a" (__tmp), "+m" (*(mem)) \ + :: "memory" ); \ __value; \ }) +#else + +#error No hardware atomic operations + +#endif /* These are the preferred public interfaces: */ diff --git a/libc/sysdeps/linux/xtensa/bits/fcntl.h b/libc/sysdeps/linux/xtensa/bits/fcntl.h index f8ae40ca7..5af9d2124 100644 --- a/libc/sysdeps/linux/xtensa/bits/fcntl.h +++ b/libc/sysdeps/linux/xtensa/bits/fcntl.h @@ -54,6 +54,7 @@ # define O_DIRECT 040000 /* Direct disk access. */ # define O_NOATIME 01000000 /* Do not set atime. */ # define O_PATH 010000000 /* Resolve pathname but do not open file. */ +# define O_TMPFILE 020200000 /* Atomically create nameless file. */ #endif /* For now Linux has synchronisity options for data and read operations. @@ -101,11 +102,13 @@ # define F_SETLEASE 1024 /* Set a lease. */ # define F_GETLEASE 1025 /* Enquire what lease is active. */ # define F_NOTIFY 1026 /* Request notfications on a directory. */ -# define F_DUPFD_CLOEXEC 1030 /* Duplicate file descriptor with - close-on-exit set on new fd. */ # define F_SETPIPE_SZ 1031 /* Set pipe page size array. */ # define F_GETPIPE_SZ 1032 /* Get pipe page size array. */ #endif +#if defined __USE_XOPEN2K8 || defined __USE_GNU +# define F_DUPFD_CLOEXEC 1030 /* Duplicate file descriptor with + close-on-exit set on new fd. */ +#endif /* For F_[GET|SET]FD. */ #define FD_CLOEXEC 1 /* actually anything with low bit set goes */ diff --git a/libc/sysdeps/linux/xtensa/bits/ipc.h b/libc/sysdeps/linux/xtensa/bits/ipc.h index 2ad5fc0a2..f4222de8c 100644 --- a/libc/sysdeps/linux/xtensa/bits/ipc.h +++ b/libc/sysdeps/linux/xtensa/bits/ipc.h @@ -48,6 +48,6 @@ struct ipc_perm __gid_t cgid; /* Creator's group ID. */ unsigned int mode; /* Read/write permission. */ unsigned int __seq; /* Sequence number. */ - unsigned long int __unused1; - unsigned long int __unused2; + unsigned long int __uclibc_unused1; + unsigned long int __uclibc_unused2; }; diff --git a/libc/sysdeps/linux/xtensa/bits/kernel_stat.h b/libc/sysdeps/linux/xtensa/bits/kernel_stat.h index 5e4f5c4e5..d884344d3 100644 --- a/libc/sysdeps/linux/xtensa/bits/kernel_stat.h +++ b/libc/sysdeps/linux/xtensa/bits/kernel_stat.h @@ -33,13 +33,13 @@ struct kernel_stat64 { unsigned long long st_rdev; /* Device number, if device. */ long long st_size; /* Size of file, in bytes. */ unsigned long st_blksize; /* Optimal block size for I/O. */ - unsigned long __unused2; + unsigned long __uclibc_unused2; unsigned long long st_blocks; /* Number 512-byte blocks allocated. */ struct timespec st_atim; /* Time of last access. */ struct timespec st_mtim; /* Time of last modification. */ struct timespec st_ctim; /* Time of last status change. */ - unsigned long __unused4; - unsigned long __unused5; + unsigned long __uclibc_unused4; + unsigned long __uclibc_unused5; }; #endif /* _BITS_STAT_STRUCT_H */ diff --git a/libc/sysdeps/linux/xtensa/bits/msq.h b/libc/sysdeps/linux/xtensa/bits/msq.h index e4f3fa317..0f65b4274 100644 --- a/libc/sysdeps/linux/xtensa/bits/msq.h +++ b/libc/sysdeps/linux/xtensa/bits/msq.h @@ -38,19 +38,19 @@ struct msqid_ds { struct ipc_perm msg_perm; /* structure describing operation permission */ #if defined (__XTENSA_EB__) - unsigned long int __unused1; + unsigned long int __uclibc_unused1; __time_t msg_stime; /* time of last msgsnd command */ - unsigned long int __unused2; + unsigned long int __uclibc_unused2; __time_t msg_rtime; /* time of last msgrcv command */ - unsigned long int __unused3; + unsigned long int __uclibc_unused3; __time_t msg_ctime; /* time of last change */ #elif defined (__XTENSA_EL__) __time_t msg_stime; /* time of last msgsnd command */ - unsigned long int __unused1; + unsigned long int __uclibc_unused1; __time_t msg_rtime; /* time of last msgrcv command */ - unsigned long int __unused2; + unsigned long int __uclibc_unused2; __time_t msg_ctime; /* time of last change */ - unsigned long int __unused3; + unsigned long int __uclibc_unused3; #else # error endian order not defined #endif @@ -59,8 +59,8 @@ struct msqid_ds msglen_t msg_qbytes; /* max number of bytes allowed on queue */ __pid_t msg_lspid; /* pid of last msgsnd() */ __pid_t msg_lrpid; /* pid of last msgrcv() */ - unsigned long int __unused4; - unsigned long int __unused5; + unsigned long int __uclibc_unused4; + unsigned long int __uclibc_unused5; }; #ifdef __USE_MISC diff --git a/libc/sysdeps/linux/xtensa/bits/shm.h b/libc/sysdeps/linux/xtensa/bits/shm.h index d288a1cca..d1e13cb49 100644 --- a/libc/sysdeps/linux/xtensa/bits/shm.h +++ b/libc/sysdeps/linux/xtensa/bits/shm.h @@ -52,17 +52,17 @@ struct shmid_ds size_t shm_segsz; /* size of segment in bytes */ #if defined (__XTENSA_EL__) __time_t shm_atime; /* time of last shmat() */ - unsigned long int __unused1; + unsigned long int __uclibc_unused1; __time_t shm_dtime; /* time of last shmdt() */ - unsigned long int __unused2; + unsigned long int __uclibc_unused2; __time_t shm_ctime; /* time of last change by shmctl() */ - unsigned long int __unused3; + unsigned long int __uclibc_unused3; #elif defined (__XTENSA_EB__) - unsigned long int __unused1; + unsigned long int __uclibc_unused1; __time_t shm_atime; /* time of last shmat() */ - unsigned long int __unused2; + unsigned long int __uclibc_unused2; __time_t shm_dtime; /* time of last shmdt() */ - unsigned long int __unused3; + unsigned long int __uclibc_unused3; __time_t shm_ctime; /* time of last change by shmctl() */ #else # error endian order not defined @@ -70,8 +70,8 @@ struct shmid_ds __pid_t shm_cpid; /* pid of creator */ __pid_t shm_lpid; /* pid of last shmop */ shmatt_t shm_nattch; /* number of current attaches */ - unsigned long int __unused4; - unsigned long int __unused5; + unsigned long int __uclibc_unused4; + unsigned long int __uclibc_unused5; }; #ifdef __USE_MISC @@ -93,10 +93,10 @@ struct shminfo unsigned long int shmmni; unsigned long int shmseg; unsigned long int shmall; - unsigned long int __unused1; - unsigned long int __unused2; - unsigned long int __unused3; - unsigned long int __unused4; + unsigned long int __uclibc_unused1; + unsigned long int __uclibc_unused2; + unsigned long int __uclibc_unused3; + unsigned long int __uclibc_unused4; }; struct shm_info diff --git a/libc/sysdeps/linux/xtensa/bits/stat.h b/libc/sysdeps/linux/xtensa/bits/stat.h index c61b188b7..045a017fd 100644 --- a/libc/sysdeps/linux/xtensa/bits/stat.h +++ b/libc/sysdeps/linux/xtensa/bits/stat.h @@ -75,8 +75,8 @@ struct stat __time_t st_ctime; /* Time of last status change. */ unsigned long int st_ctimensec; /* Nsecs of last status change. */ #endif - unsigned long int __unused4; - unsigned long int __unused5; + unsigned long int __uclibc_unused4; + unsigned long int __uclibc_unused5; }; #ifdef __USE_LARGEFILE64 @@ -112,8 +112,8 @@ struct stat64 __time_t st_ctime; /* Time of last status change. */ unsigned long int st_ctimensec; /* Nsecs of last status change. */ #endif - unsigned long __unused4; - unsigned long __unused5; + unsigned long __uclibc_unused4; + unsigned long __uclibc_unused5; }; #endif diff --git a/libc/sysdeps/linux/xtensa/bits/xtensa-config.h b/libc/sysdeps/linux/xtensa/bits/xtensa-config.h index 2e60af936..b99928b1e 100644 --- a/libc/sysdeps/linux/xtensa/bits/xtensa-config.h +++ b/libc/sysdeps/linux/xtensa/bits/xtensa-config.h @@ -43,4 +43,10 @@ #undef XCHAL_NUM_AREGS #define XCHAL_NUM_AREGS 64 +#undef XCHAL_HAVE_S32C1I +#define XCHAL_HAVE_S32C1I 1 + +#undef XCHAL_HAVE_EXCLUSIVE +#define XCHAL_HAVE_EXCLUSIVE 0 + #endif /* !XTENSA_CONFIG_H */ diff --git a/libc/sysdeps/linux/xtensa/crt1.S b/libc/sysdeps/linux/xtensa/crt1.S index efbe264c0..3fa14ae58 100644 --- a/libc/sysdeps/linux/xtensa/crt1.S +++ b/libc/sysdeps/linux/xtensa/crt1.S @@ -76,9 +76,26 @@ .global _start .type _start, @function _start: +#ifdef L_rcrt1 + .begin no-transform + call0 1f +.Lret_addr: + .end no-transform + .align 4 +1: +#endif #if defined(__XTENSA_WINDOWED_ABI__) +#ifdef L_rcrt1 + movi a6, .Lret_addr + sub a6, a0, a6 + movi a0, 0 + movi a4, reloc_static_pie + add a4, a4, a6 + callx4 a4 +#else /* Clear a0 to obviously mark the outermost frame. */ movi a0, 0 +#endif /* Load up the user's main function. */ movi a6, main @@ -106,8 +123,18 @@ _start: movi a4, __uClibc_main callx4 a4 #elif defined(__XTENSA_CALL0_ABI__) +#ifdef L_rcrt1 + mov a12, a2 + movi a2, .Lret_addr + sub a2, a0, a2 + movi a0, reloc_static_pie + add a0, a0, a2 + callx0 a0 + mov a7, a12 +#else /* Setup the shared library termination function. */ mov a7, a2 +#endif /* Load up the user's main function. */ movi a2, main diff --git a/libc/sysdeps/linux/xtensa/getcontext.S b/libc/sysdeps/linux/xtensa/getcontext.S new file mode 100644 index 000000000..7588a91b3 --- /dev/null +++ b/libc/sysdeps/linux/xtensa/getcontext.S @@ -0,0 +1,99 @@ +/* Copyright (C) 2018 - 2022 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <sysdep.h> +#include "ucontext_i.h" + +#if defined(__XTENSA_CALL0_ABI__) +ENTRY(__getcontext) + s32i a0, a2, MCONTEXT_SC_PC + s32i a1, a2, MCONTEXT_SC_A_0 + 4 + + /* save callee-saved registers in the context */ + s32i a12, a2, MCONTEXT_SC_A_0 + 48 + s32i a13, a2, MCONTEXT_SC_A_0 + 52 + s32i a14, a2, MCONTEXT_SC_A_0 + 56 + s32i a15, a2, MCONTEXT_SC_A_0 + 60 + + movi a3, 0 + addi a4, a2, UCONTEXT_SIGMASK + movi a2, SIG_BLOCK + movi a5, JUMPTARGET (sigprocmask) + jx a5 +END(__getcontext) +#elif defined(__XTENSA_WINDOWED_ABI__) +ENTRY(__getcontext) + movi a4, __window_spill + callx4 a4 + s32i a0, a2, MCONTEXT_SC_PC + + /* copy registers a0..a3 from spill area */ + addi a3, a1, -16 + l32i a4, a3, 0 + l32i a5, a3, 4 + l32i a6, a3, 8 + l32i a7, a3, 12 + s32i a4, a2, MCONTEXT_SC_A_0 + 0 + s32i a5, a2, MCONTEXT_SC_A_0 + 4 + s32i a6, a2, MCONTEXT_SC_A_0 + 8 + s32i a7, a2, MCONTEXT_SC_A_0 + 12 + + /* if it was call4 then register saving is done */ + extui a4, a0, 30, 2 + bltui a4, 2, 1f + + /* otherwise load spill overflow area address into a3 */ + addi a3, a5, -16 + l32i a3, a3, 4 + addi a3, a3, -32 + beqi a4, 2, 2f + + /* copy registers a8..a11 from spill overflow area */ + addi a3, a3, -16 + l32i a4, a3, 16 + l32i a5, a3, 20 + l32i a6, a3, 24 + l32i a7, a3, 28 + s32i a4, a2, MCONTEXT_SC_A_0 + 32 + s32i a5, a2, MCONTEXT_SC_A_0 + 36 + s32i a6, a2, MCONTEXT_SC_A_0 + 40 + s32i a7, a2, MCONTEXT_SC_A_0 + 44 + + /* copy registers a4..a7 from spill overflow area */ +2: + l32i a4, a3, 0 + l32i a5, a3, 4 + l32i a6, a3, 8 + l32i a7, a3, 12 + s32i a4, a2, MCONTEXT_SC_A_0 + 16 + s32i a5, a2, MCONTEXT_SC_A_0 + 20 + s32i a6, a2, MCONTEXT_SC_A_0 + 24 + s32i a7, a2, MCONTEXT_SC_A_0 + 28 +1: + movi a6, SIG_BLOCK + movi a7, 0 + addi a8, a2, UCONTEXT_SIGMASK + movi a4, JUMPTARGET (sigprocmask) + callx4 a4 + mov a2, a6 + retw +END(__getcontext) +#else +#error Unsupported Xtensa ABI +#endif + +weak_alias (__getcontext, getcontext) diff --git a/libc/sysdeps/linux/xtensa/makecontext.c b/libc/sysdeps/linux/xtensa/makecontext.c new file mode 100644 index 000000000..da26a0130 --- /dev/null +++ b/libc/sysdeps/linux/xtensa/makecontext.c @@ -0,0 +1,179 @@ +/* Copyright (C) 2018 - 2022 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <sysdep.h> +#include <stdarg.h> +#include <stdint.h> +#include <string.h> +#include <ucontext.h> + +extern void __start_context (void); + +#if defined(__XTENSA_CALL0_ABI__) +/* + * makecontext sets up new stack like this: + * + * +------------------ stack top (uc_stack.ss_sp + uc_stack.ss_size) + * | optional alignment + * +------------------ CFA of __start_context, initial sp points here + * | optional padding + * +------------------ Optional arguments 6..argc - 1 + * | func arg argc - 1 + * | func arg argc - 2 + * | ... + * | func arg 6 + * +------------------ Optional arguments 2..5 + * | func arg 5 + * 16 | func arg 4 + * | func arg 3 + * | func arg 2 + * +------------------ Optional arguments 0..1 + * | func arg 1 + * 16 | func arg 0 + * | padding + * | padding + * +------------------ CFA of pseudo getcontext + * | + * +------------------ stack bottom (uc_stack.ss_sp) + * + * When argc is 0 arguments areas are not allocated, + * when 1 <= argc < 3 only area for arguments 0..1 is allocated, + * when 3 <= argc < 7 areas for arguments 0..1 and 2..5 is allocated, + * when argc >= 7 all three arguments areas are allocated. + * Arguments 0..5 area is deallocated by the __start_context after + * arguments are loaded into registers. + * uc_mcontext registers are set as if __start_context made call0 + * to getcontext, sp points to that pseudo getcontext CFA. + * setcontext/swapcontext will arrange for restoring regiters + * a1, a12..a15 of __start_context. + */ + +void +__makecontext (ucontext_t *ucp, void (*func) (void), int argc, ...) +{ + unsigned long sp = ((unsigned long) ucp->uc_stack.ss_sp + + ucp->uc_stack.ss_size) & -16; + int i; + + if (argc > 0) + sp -= 4 * (argc + 2); + sp &= -16; + + ucp->uc_mcontext.sc_pc = (unsigned long) __start_context; + ucp->uc_mcontext.sc_a[1] = sp; + ucp->uc_mcontext.sc_a[12] = (unsigned long) func; + ucp->uc_mcontext.sc_a[13] = (unsigned long) ucp->uc_link; + ucp->uc_mcontext.sc_a[14] = argc; + + if (argc) + { + va_list ap; + + va_start (ap, argc); + for (i = 0; i < argc; ++i) + ((int *) sp)[i + 2] = va_arg (ap, int); + va_end (ap); + } +} +#elif defined(__XTENSA_WINDOWED_ABI__) +/* + * makecontext sets up new stack like this: + * + * +------------------ stack top (uc_stack.ss_sp + uc_stack.ss_size) + * | optional alignment + * +------------------ CFA of __start_context + * 16 | Outermost caller spill area + * +------------------ + * 16 | __start_context overflow area + * +------------------ initial sp points here + * | optional padding + * +------------------ Optional arguments 6..argc - 1 + * | func arg argc - 1 + * | func arg argc - 2 + * | ... + * | func arg 6 + * +------------------ Optional arguments 3..5 + * | func arg 5 + * 16 | func arg 4 + * | func arg 3 + * | padding + * +------------------ CFA of pseudo getcontext + * 16 | __start_context caller spill area + * +------------------ + * | + * +------------------ stack bottom (uc_stack.ss_sp) + * + * When argc < 4 both arguments areas are not allocated, + * when 4 <= argc < 7 only area for arguments 3..5 is allocated, + * when argc >= 7 both arguments areas are allocated. + * Arguments 3..5 area is deallocated by the __start_context after + * arguments are loaded into registers. + * uc_mcontext registers are set as if __start_context made call8 + * to getcontext, sp points to that pseudo getcontext CFA, spill + * area under that sp has a1 pointing to the __start_context CFA + * at the top of the stack. setcontext/swapcontext will arrange for + * restoring regiters a0..a7 of __start_context. + */ + +void +__makecontext (ucontext_t *ucp, void (*func) (void), int argc, ...) +{ + unsigned long sp = ((unsigned long) ucp->uc_stack.ss_sp + + ucp->uc_stack.ss_size - 32) & -16; + unsigned long spill0[4] = + { + 0, sp + 32, 0, 0, + }; + int i; + + memset ((void *) sp, 0, 32); + + if (argc > 2) + sp -= 4 * (argc - 2); + sp &= -16; + + ucp->uc_mcontext.sc_pc = + ((unsigned long) __start_context & 0x3fffffff) + 0x80000000; + ucp->uc_mcontext.sc_a[0] = 0; + ucp->uc_mcontext.sc_a[1] = sp; + ucp->uc_mcontext.sc_a[2] = (unsigned long) func; + ucp->uc_mcontext.sc_a[3] = (unsigned long) ucp->uc_link; + ucp->uc_mcontext.sc_a[4] = argc; + + if (argc) + { + va_list ap; + + va_start (ap, argc); + for (i = 0; i < argc; ++i) + { + if (i < 3) + ucp->uc_mcontext.sc_a[5 + i] = va_arg (ap, int); + else + ((int *) sp)[i - 2] = va_arg (ap, int); + } + va_end (ap); + } + + sp -= 16; + memcpy ((void *) sp, spill0, sizeof (spill0)); +} +#else +#error Unsupported Xtensa ABI +#endif + +weak_alias (__makecontext, makecontext) diff --git a/libc/sysdeps/linux/xtensa/setcontext.S b/libc/sysdeps/linux/xtensa/setcontext.S new file mode 100644 index 000000000..4df7cc049 --- /dev/null +++ b/libc/sysdeps/linux/xtensa/setcontext.S @@ -0,0 +1,116 @@ +/* Copyright (C) 2018 - 2022 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <sysdep.h> +#include "ucontext_i.h" + +#if defined(__XTENSA_CALL0_ABI__) +ENTRY(__setcontext) + addi sp, sp, -16 + s32i a0, sp, 0 + s32i a2, sp, 4 + + addi a3, a2, UCONTEXT_SIGMASK + movi a4, 0 + movi a2, SIG_SETMASK + movi a5, JUMPTARGET (sigprocmask) + callx0 a5 + bnez a2, .Lerror + + l32i a2, sp, 4 + l32i a0, a2, MCONTEXT_SC_PC + l32i a1, a2, MCONTEXT_SC_A_0 + 4 + + /* load callee-saved registers from the context */ + l32i a12, a2, MCONTEXT_SC_A_0 + 48 + l32i a13, a2, MCONTEXT_SC_A_0 + 52 + l32i a14, a2, MCONTEXT_SC_A_0 + 56 + l32i a15, a2, MCONTEXT_SC_A_0 + 60 + movi a2, 0 + ret +.Lerror: + l32i a0, sp, 0 + addi sp, sp, 16 + ret +END(__setcontext) +#elif defined(__XTENSA_WINDOWED_ABI__) +ENTRY(__setcontext) + movi a6, SIG_SETMASK + addi a7, a2, UCONTEXT_SIGMASK + movi a8, 0 + movi a4, JUMPTARGET (sigprocmask) + callx4 a4 + bnez a6, .Lerror + movi a4, __window_spill + callx4 a4 + + l32i a0, a2, MCONTEXT_SC_PC + + /* copy registers a0..a3 to spill area */ + addi a3, a1, -16 + l32i a4, a2, MCONTEXT_SC_A_0 + 0 + l32i a5, a2, MCONTEXT_SC_A_0 + 4 + l32i a6, a2, MCONTEXT_SC_A_0 + 8 + l32i a7, a2, MCONTEXT_SC_A_0 + 12 + s32i a4, a3, 0 + s32i a5, a3, 4 + s32i a6, a3, 8 + s32i a7, a3, 12 + + /* if it was call4 then register setup is done */ + extui a4, a0, 30, 2 + bltui a4, 2, 1f + + /* otherwise load spill overflow area address into a3 */ + addi a3, a5, -16 + l32i a3, a3, 4 + addi a3, a3, -32 + beqi a4, 2, 2f + + /* copy registers a8..a11 to spill overflow area */ + addi a3, a3, -16 + l32i a4, a2, MCONTEXT_SC_A_0 + 32 + l32i a5, a2, MCONTEXT_SC_A_0 + 36 + l32i a6, a2, MCONTEXT_SC_A_0 + 40 + l32i a7, a2, MCONTEXT_SC_A_0 + 44 + s32i a4, a3, 16 + s32i a5, a3, 20 + s32i a6, a3, 24 + s32i a7, a3, 28 + + /* copy registers a4..a7 to spill overflow area */ +2: + l32i a4, a2, MCONTEXT_SC_A_0 + 16 + l32i a5, a2, MCONTEXT_SC_A_0 + 20 + l32i a6, a2, MCONTEXT_SC_A_0 + 24 + l32i a7, a2, MCONTEXT_SC_A_0 + 28 + s32i a4, a3, 0 + s32i a5, a3, 4 + s32i a6, a3, 8 + s32i a7, a3, 12 +1: + movi a2, 0 + retw +.Lerror: + mov a2, a6 + retw +END(__setcontext) +#else +#error Unsupported Xtensa ABI +#endif + +weak_alias (__setcontext, setcontext) diff --git a/libc/sysdeps/linux/xtensa/swapcontext.S b/libc/sysdeps/linux/xtensa/swapcontext.S new file mode 100644 index 000000000..a215edc6d --- /dev/null +++ b/libc/sysdeps/linux/xtensa/swapcontext.S @@ -0,0 +1,173 @@ +/* Copyright (C) 2018 - 2022 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <sysdep.h> +#include "ucontext_i.h" + +#if defined(__XTENSA_CALL0_ABI__) +ENTRY(__swapcontext) + s32i a0, a2, MCONTEXT_SC_PC + s32i a1, a2, MCONTEXT_SC_A_0 + 4 + + /* save callee-saved registers in the context */ + s32i a12, a2, MCONTEXT_SC_A_0 + 48 + s32i a13, a2, MCONTEXT_SC_A_0 + 52 + s32i a14, a2, MCONTEXT_SC_A_0 + 56 + s32i a15, a2, MCONTEXT_SC_A_0 + 60 + + mov a12, a3 + mov a13, a2 + + addi a3, a3, UCONTEXT_SIGMASK + addi a4, a2, UCONTEXT_SIGMASK + movi a2, SIG_SETMASK + movi a5, JUMPTARGET (sigprocmask) + callx0 a5 + bnez a2, .Lerror + + mov a2, a12 + l32i a0, a2, MCONTEXT_SC_PC + l32i a1, a2, MCONTEXT_SC_A_0 + 4 + + /* load callee-saved registers from the context */ + l32i a12, a2, MCONTEXT_SC_A_0 + 48 + l32i a13, a2, MCONTEXT_SC_A_0 + 52 + l32i a14, a2, MCONTEXT_SC_A_0 + 56 + l32i a15, a2, MCONTEXT_SC_A_0 + 60 + + movi a2, 0 + ret +.Lerror: + l32i a0, a13, MCONTEXT_SC_PC + l32i a12, a13, MCONTEXT_SC_A_0 + 48 + l32i a13, a13, MCONTEXT_SC_A_0 + 52 + ret +END(__swapcontext) +#elif defined(__XTENSA_WINDOWED_ABI__) +ENTRY(__swapcontext) + movi a4, __window_spill + callx4 a4 + mov a9, a3 + s32i a0, a2, MCONTEXT_SC_PC + + /* copy registers a0..a3 from spill area */ + addi a3, a1, -16 + l32i a4, a3, 0 + l32i a5, a3, 4 + l32i a6, a3, 8 + l32i a7, a3, 12 + s32i a4, a2, MCONTEXT_SC_A_0 + 0 + s32i a5, a2, MCONTEXT_SC_A_0 + 4 + s32i a6, a2, MCONTEXT_SC_A_0 + 8 + s32i a7, a2, MCONTEXT_SC_A_0 + 12 + + /* if it was call4 then register saving is done */ + extui a4, a0, 30, 2 + bltui a4, 2, 1f + + /* otherwise load spill overflow area address into a3 */ + addi a3, a5, -16 + l32i a3, a3, 4 + addi a3, a3, -32 + beqi a4, 2, 2f + + /* copy registers a8..a11 from spill overflow area */ + addi a3, a3, -16 + l32i a4, a3, 16 + l32i a5, a3, 20 + l32i a6, a3, 24 + l32i a7, a3, 28 + s32i a4, a2, MCONTEXT_SC_A_0 + 32 + s32i a5, a2, MCONTEXT_SC_A_0 + 36 + s32i a6, a2, MCONTEXT_SC_A_0 + 40 + s32i a7, a2, MCONTEXT_SC_A_0 + 44 + + /* copy registers a4..a7 from spill overflow area */ +2: + l32i a4, a3, 0 + l32i a5, a3, 4 + l32i a6, a3, 8 + l32i a7, a3, 12 + s32i a4, a2, MCONTEXT_SC_A_0 + 16 + s32i a5, a2, MCONTEXT_SC_A_0 + 20 + s32i a6, a2, MCONTEXT_SC_A_0 + 24 + s32i a7, a2, MCONTEXT_SC_A_0 + 28 +1: + movi a6, SIG_SETMASK + addi a7, a9, UCONTEXT_SIGMASK + addi a8, a2, UCONTEXT_SIGMASK + mov a2, a9 + movi a4, JUMPTARGET (sigprocmask) + callx4 a4 + bnez a6, .Lerror + + l32i a0, a2, MCONTEXT_SC_PC + + /* copy registers a0..a3 to spill area */ + addi a3, a1, -16 + l32i a4, a2, MCONTEXT_SC_A_0 + 0 + l32i a5, a2, MCONTEXT_SC_A_0 + 4 + l32i a6, a2, MCONTEXT_SC_A_0 + 8 + l32i a7, a2, MCONTEXT_SC_A_0 + 12 + s32i a4, a3, 0 + s32i a5, a3, 4 + s32i a6, a3, 8 + s32i a7, a3, 12 + + /* if it was call4 then register setup is done */ + extui a4, a0, 30, 2 + bltui a4, 2, 1f + + /* otherwise load spill overflow area address into a3 */ + addi a3, a5, -16 + l32i a3, a3, 4 + addi a3, a3, -32 + beqi a4, 2, 2f + + /* copy registers a8..a11 to spill overflow area */ + addi a3, a3, -16 + l32i a4, a2, MCONTEXT_SC_A_0 + 32 + l32i a5, a2, MCONTEXT_SC_A_0 + 36 + l32i a6, a2, MCONTEXT_SC_A_0 + 40 + l32i a7, a2, MCONTEXT_SC_A_0 + 44 + s32i a4, a3, 16 + s32i a5, a3, 20 + s32i a6, a3, 24 + s32i a7, a3, 28 + + /* copy registers a4..a7 to spill overflow area */ +2: + l32i a4, a2, MCONTEXT_SC_A_0 + 16 + l32i a5, a2, MCONTEXT_SC_A_0 + 20 + l32i a6, a2, MCONTEXT_SC_A_0 + 24 + l32i a7, a2, MCONTEXT_SC_A_0 + 28 + s32i a4, a3, 0 + s32i a5, a3, 4 + s32i a6, a3, 8 + s32i a7, a3, 12 +1: + movi a2, 0 + retw +.Lerror: + mov a2, a6 + retw +END(__swapcontext) +#else +#error Unsupported Xtensa ABI +#endif + +weak_alias (__swapcontext, swapcontext) diff --git a/libc/sysdeps/linux/xtensa/sysdep.h b/libc/sysdeps/linux/xtensa/sysdep.h index 0671f0783..80b3f30fc 100644 --- a/libc/sysdeps/linux/xtensa/sysdep.h +++ b/libc/sysdeps/linux/xtensa/sysdep.h @@ -39,12 +39,15 @@ #endif -#define ENTRY(name) \ +#define ENTRY_PREFIX(name) \ .globl C_SYMBOL_NAME(name); \ ASM_TYPE_DIRECTIVE (C_SYMBOL_NAME(name), @function); \ .align ALIGNARG(2); \ LITERAL_POSITION; \ - C_LABEL(name) \ + C_LABEL(name) + +#define ENTRY(name) \ + ENTRY_PREFIX(name) \ abi_entry(sp, FRAMESIZE); #define HIDDEN_ENTRY(name) \ diff --git a/libc/sysdeps/linux/xtensa/ucontext_i.sym b/libc/sysdeps/linux/xtensa/ucontext_i.sym new file mode 100644 index 000000000..4770c36c9 --- /dev/null +++ b/libc/sysdeps/linux/xtensa/ucontext_i.sym @@ -0,0 +1,15 @@ +#include <inttypes.h> +#include <signal.h> +#include <stddef.h> +#include <sys/ucontext.h> + +SIG_BLOCK +SIG_SETMASK + +-- Offsets of the fields in the ucontext_t structure. +#define ucontext(member) offsetof (ucontext_t, member) +#define mcontext(member) ucontext (uc_mcontext.member) + +UCONTEXT_SIGMASK ucontext (uc_sigmask) +MCONTEXT_SC_A_0 mcontext (sc_a[0]) +MCONTEXT_SC_PC mcontext (sc_pc) |