mailing list of musl libc
 help / color / mirror / code / Atom feed
* [musl] [PATCH 00/14] riscv32 support
@ 2020-09-03 11:22 Stefan O'Rear
  2020-09-03 11:22 ` [musl] [PATCH 01/14] Remove ARMSUBARCH relic from configure Stefan O'Rear
                   ` (13 more replies)
  0 siblings, 14 replies; 31+ messages in thread
From: Stefan O'Rear @ 2020-09-03 11:22 UTC (permalink / raw)
  To: musl; +Cc: Stefan O'Rear

Several changes to support architectures without time32 syscalls, and
then a riscv32 port (created by copying the riscv64 files and changing
as necessary).

Cleanup in configure is related only insofar as I spent time determining
what it did while researching musl's ARCH/SUBARCH system, and removing
the relic will slightly speed up future ports.

I don't have a great handle on how musl handles files (what should they
be called, where should they be, whether include guards should be used
and whether headers should include everything they depend on) and would
particularly welcome feedback on that.  Likewise I don't have a good
model of the musl whitespace and paren style.

Requires Linux 5.4 for full functionality due to using waitid(P_PGID,0)
to emulate waitpid(0); earlier kernels may be supported on a best-effort
basis.

Testing so far has consisted of building openembedded with TCLIBC=musl
and the patch added to the musl recipe, booting the resulting images,
and running the strace build system in the VM.  This includes systemd
with the openembedded musl compatibilty patches.  strace does not work
(it prints a spurious SIGTRAP message and then the tracee runs
untraced).  Further testing and debugging will continue.

Testing on non-riscv32 architectures also remains to be done.

Stefan O'Rear (14):
  Remove ARMSUBARCH relic from configure
  time64: Don't make aliases to nonexistent syscalls
  time64: Only getrlimit/setrlimit if they exist
  time64: Only gettimeofday/settimeofday if exist
  Add src/internal/statx.h
  Only call fstatat if defined
  Emulate wait4 using waitid
  riscv: Fall back to syscall __riscv_flush_icache
  riscv32: Target and subtarget detection
  riscv32: add arch headers
  riscv32: Add fenv and math
  riscv32: Add dlsym
  riscv32: Add jmp_buf and sigreturn
  riscv32: Add thread support

 arch/riscv32/atomic_arch.h             |  21 ++
 arch/riscv32/bits/alltypes.h.in        |  18 ++
 arch/riscv32/bits/fcntl.h              |  38 ++++
 arch/riscv32/bits/fenv.h               |  17 ++
 arch/riscv32/bits/float.h              |  16 ++
 arch/riscv32/bits/posix.h              |   2 +
 arch/riscv32/bits/setjmp.h             |   1 +
 arch/riscv32/bits/signal.h             | 118 ++++++++++
 arch/riscv32/bits/stat.h               |  18 ++
 arch/riscv32/bits/stdint.h             |  20 ++
 arch/riscv32/bits/syscall.h.in         | 284 +++++++++++++++++++++++++
 arch/riscv32/bits/user.h               |   5 +
 arch/riscv32/crt_arch.h                |  19 ++
 arch/riscv32/kstat.h                   |   0
 arch/riscv32/pthread_arch.h            |  13 ++
 arch/riscv32/reloc.h                   |  22 ++
 arch/riscv32/syscall_arch.h            |  78 +++++++
 configure                              |   8 +-
 src/fenv/riscv32/fenv-sf.c             |   3 +
 src/fenv/riscv32/fenv.S                |  56 +++++
 src/internal/statx.h                   |  28 +++
 src/internal/syscall.h                 |   2 +
 src/internal/wait4_waitid.h            |   1 +
 src/ldso/riscv32/dlsym.s               |   6 +
 src/linux/__wait4_waitid.c             |  52 +++++
 src/linux/cache.c                      |   1 +
 src/linux/wait4.c                      |   5 +
 src/math/riscv32/copysign.c            |  15 ++
 src/math/riscv32/copysignf.c           |  15 ++
 src/math/riscv32/fabs.c                |  15 ++
 src/math/riscv32/fabsf.c               |  15 ++
 src/math/riscv32/fma.c                 |  15 ++
 src/math/riscv32/fmaf.c                |  15 ++
 src/math/riscv32/fmax.c                |  15 ++
 src/math/riscv32/fmaxf.c               |  15 ++
 src/math/riscv32/fmin.c                |  15 ++
 src/math/riscv32/fminf.c               |  15 ++
 src/math/riscv32/sqrt.c                |  15 ++
 src/math/riscv32/sqrtf.c               |  15 ++
 src/misc/getrlimit.c                   |   6 +-
 src/misc/setrlimit.c                   |   6 +-
 src/process/waitpid.c                  |   6 +
 src/setjmp/riscv32/longjmp.S           |  42 ++++
 src/setjmp/riscv32/setjmp.S            |  41 ++++
 src/signal/riscv32/restore.s           |   8 +
 src/signal/riscv32/sigsetjmp.s         |  23 ++
 src/stat/fchmodat.c                    |  22 +-
 src/stat/fstatat.c                     |  34 +--
 src/stdio/pclose.c                     |   6 +
 src/stdio/tempnam.c                    |   7 +
 src/stdio/tmpnam.c                     |   7 +
 src/thread/riscv32/__set_thread_area.s |   6 +
 src/thread/riscv32/__unmapself.s       |   7 +
 src/thread/riscv32/clone.s             |  34 +++
 src/thread/riscv32/syscall_cp.s        |  29 +++
 src/time/__map_file.c                  |  13 +-
 src/time/clock_gettime.c               |   4 +
 src/unistd/faccessat.c                 |   6 +-
 58 files changed, 1302 insertions(+), 37 deletions(-)
 create mode 100644 arch/riscv32/atomic_arch.h
 create mode 100644 arch/riscv32/bits/alltypes.h.in
 create mode 100644 arch/riscv32/bits/fcntl.h
 create mode 100644 arch/riscv32/bits/fenv.h
 create mode 100644 arch/riscv32/bits/float.h
 create mode 100644 arch/riscv32/bits/posix.h
 create mode 100644 arch/riscv32/bits/setjmp.h
 create mode 100644 arch/riscv32/bits/signal.h
 create mode 100644 arch/riscv32/bits/stat.h
 create mode 100644 arch/riscv32/bits/stdint.h
 create mode 100644 arch/riscv32/bits/syscall.h.in
 create mode 100644 arch/riscv32/bits/user.h
 create mode 100644 arch/riscv32/crt_arch.h
 create mode 100644 arch/riscv32/kstat.h
 create mode 100644 arch/riscv32/pthread_arch.h
 create mode 100644 arch/riscv32/reloc.h
 create mode 100644 arch/riscv32/syscall_arch.h
 create mode 100644 src/fenv/riscv32/fenv-sf.c
 create mode 100644 src/fenv/riscv32/fenv.S
 create mode 100644 src/internal/statx.h
 create mode 100644 src/internal/wait4_waitid.h
 create mode 100644 src/ldso/riscv32/dlsym.s
 create mode 100644 src/linux/__wait4_waitid.c
 create mode 100644 src/math/riscv32/copysign.c
 create mode 100644 src/math/riscv32/copysignf.c
 create mode 100644 src/math/riscv32/fabs.c
 create mode 100644 src/math/riscv32/fabsf.c
 create mode 100644 src/math/riscv32/fma.c
 create mode 100644 src/math/riscv32/fmaf.c
 create mode 100644 src/math/riscv32/fmax.c
 create mode 100644 src/math/riscv32/fmaxf.c
 create mode 100644 src/math/riscv32/fmin.c
 create mode 100644 src/math/riscv32/fminf.c
 create mode 100644 src/math/riscv32/sqrt.c
 create mode 100644 src/math/riscv32/sqrtf.c
 create mode 100644 src/setjmp/riscv32/longjmp.S
 create mode 100644 src/setjmp/riscv32/setjmp.S
 create mode 100644 src/signal/riscv32/restore.s
 create mode 100644 src/signal/riscv32/sigsetjmp.s
 create mode 100644 src/thread/riscv32/__set_thread_area.s
 create mode 100644 src/thread/riscv32/__unmapself.s
 create mode 100644 src/thread/riscv32/clone.s
 create mode 100644 src/thread/riscv32/syscall_cp.s

-- 
2.25.4


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

* [musl] [PATCH 01/14] Remove ARMSUBARCH relic from configure
  2020-09-03 11:22 [musl] [PATCH 00/14] riscv32 support Stefan O'Rear
@ 2020-09-03 11:22 ` Stefan O'Rear
  2020-09-03 11:22 ` [musl] [PATCH 02/14] time64: Don't make aliases to nonexistent syscalls Stefan O'Rear
                   ` (12 subsequent siblings)
  13 siblings, 0 replies; 31+ messages in thread
From: Stefan O'Rear @ 2020-09-03 11:22 UTC (permalink / raw)
  To: musl; +Cc: Stefan O'Rear

---
 configure | 5 -----
 1 file changed, 5 deletions(-)

diff --git a/configure b/configure
index 947adf41..49a7b403 100755
--- a/configure
+++ b/configure
@@ -725,11 +725,6 @@ fi
 test "$SUBARCH" \
 && printf "configured for %s variant: %s\n" "$ARCH" "$ARCH$SUBARCH"
 
-case "$ARCH$SUBARCH" in
-arm) ASMSUBARCH=el ;;
-*) ASMSUBARCH=$SUBARCH ;;
-esac
-
 #
 # Some archs (powerpc) have different possible long double formats
 # that the compiler can be configured for. The logic for whether this
-- 
2.25.4


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

* [musl] [PATCH 02/14] time64: Don't make aliases to nonexistent syscalls
  2020-09-03 11:22 [musl] [PATCH 00/14] riscv32 support Stefan O'Rear
  2020-09-03 11:22 ` [musl] [PATCH 01/14] Remove ARMSUBARCH relic from configure Stefan O'Rear
@ 2020-09-03 11:22 ` Stefan O'Rear
  2020-09-03 15:56   ` Rich Felker
  2020-09-03 11:22 ` [musl] [PATCH 03/14] time64: Only getrlimit/setrlimit if they exist Stefan O'Rear
                   ` (11 subsequent siblings)
  13 siblings, 1 reply; 31+ messages in thread
From: Stefan O'Rear @ 2020-09-03 11:22 UTC (permalink / raw)
  To: musl; +Cc: Stefan O'Rear

riscv32 and future architectures lack the _time32 variants entirely, so
don't try to use their numbers.
---
 src/internal/syscall.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/src/internal/syscall.h b/src/internal/syscall.h
index d5f294d4..66fc4e5c 100644
--- a/src/internal/syscall.h
+++ b/src/internal/syscall.h
@@ -201,6 +201,7 @@ static inline long __alt_socketcall(int sys, int sock, int cp, long a, long b, l
 #define SYS_sendfile SYS_sendfile64
 #endif
 
+#ifdef SYS_timer_settime32
 #ifndef SYS_timer_settime
 #define SYS_timer_settime SYS_timer_settime32
 #endif
@@ -240,6 +241,7 @@ static inline long __alt_socketcall(int sys, int sock, int cp, long a, long b, l
 #ifndef SYS_settimeofday
 #define SYS_settimeofday SYS_settimeofday_time32
 #endif
+#endif
 
 /* Ensure that the plain syscall names are defined even for "time64-only"
  * archs. These facilitate callers passing null time arguments, and make
-- 
2.25.4


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

* [musl] [PATCH 03/14] time64: Only getrlimit/setrlimit if they exist
  2020-09-03 11:22 [musl] [PATCH 00/14] riscv32 support Stefan O'Rear
  2020-09-03 11:22 ` [musl] [PATCH 01/14] Remove ARMSUBARCH relic from configure Stefan O'Rear
  2020-09-03 11:22 ` [musl] [PATCH 02/14] time64: Don't make aliases to nonexistent syscalls Stefan O'Rear
@ 2020-09-03 11:22 ` Stefan O'Rear
  2020-09-03 11:22 ` [musl] [PATCH 04/14] time64: Only gettimeofday/settimeofday if exist Stefan O'Rear
                   ` (10 subsequent siblings)
  13 siblings, 0 replies; 31+ messages in thread
From: Stefan O'Rear @ 2020-09-03 11:22 UTC (permalink / raw)
  To: musl; +Cc: Stefan O'Rear

riscv32 and future architectures only provide prlimit64.
---
 src/misc/getrlimit.c | 6 +++++-
 src/misc/setrlimit.c | 6 +++++-
 2 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/src/misc/getrlimit.c b/src/misc/getrlimit.c
index 2ab2f0f4..bf676307 100644
--- a/src/misc/getrlimit.c
+++ b/src/misc/getrlimit.c
@@ -6,12 +6,13 @@
 
 int getrlimit(int resource, struct rlimit *rlim)
 {
-	unsigned long k_rlim[2];
 	int ret = syscall(SYS_prlimit64, 0, resource, 0, rlim);
 	if (!ret) {
 		FIX(rlim->rlim_cur);
 		FIX(rlim->rlim_max);
 	}
+#ifdef SYS_getrlimit
+	unsigned long k_rlim[2];
 	if (!ret || errno != ENOSYS)
 		return ret;
 	if (syscall(SYS_getrlimit, resource, k_rlim) < 0)
@@ -21,6 +22,9 @@ int getrlimit(int resource, struct rlimit *rlim)
 	FIX(rlim->rlim_cur);
 	FIX(rlim->rlim_max);
 	return 0;
+#else
+	return ret;
+#endif
 }
 
 weak_alias(getrlimit, getrlimit64);
diff --git a/src/misc/setrlimit.c b/src/misc/setrlimit.c
index 7a66ab29..62eba5f3 100644
--- a/src/misc/setrlimit.c
+++ b/src/misc/setrlimit.c
@@ -8,7 +8,6 @@
 
 static int __setrlimit(int resource, const struct rlimit *rlim)
 {
-	unsigned long k_rlim[2];
 	struct rlimit tmp;
 	if (SYSCALL_RLIM_INFINITY != RLIM_INFINITY) {
 		tmp = *rlim;
@@ -17,10 +16,15 @@ static int __setrlimit(int resource, const struct rlimit *rlim)
 		rlim = &tmp;
 	}
 	int ret = __syscall(SYS_prlimit64, 0, resource, rlim, 0);
+#ifdef SYS_setrlimit
+	unsigned long k_rlim[2];
 	if (ret != -ENOSYS) return ret;
 	k_rlim[0] = MIN(rlim->rlim_cur, MIN(-1UL, SYSCALL_RLIM_INFINITY));
 	k_rlim[1] = MIN(rlim->rlim_max, MIN(-1UL, SYSCALL_RLIM_INFINITY));
 	return __syscall(SYS_setrlimit, resource, k_rlim);
+#else
+	return ret;
+#endif
 }
 
 struct ctx {
-- 
2.25.4


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

* [musl] [PATCH 04/14] time64: Only gettimeofday/settimeofday if exist
  2020-09-03 11:22 [musl] [PATCH 00/14] riscv32 support Stefan O'Rear
                   ` (2 preceding siblings ...)
  2020-09-03 11:22 ` [musl] [PATCH 03/14] time64: Only getrlimit/setrlimit if they exist Stefan O'Rear
@ 2020-09-03 11:22 ` Stefan O'Rear
  2020-09-03 11:23 ` [musl] [PATCH 05/14] Add src/internal/statx.h Stefan O'Rear
                   ` (9 subsequent siblings)
  13 siblings, 0 replies; 31+ messages in thread
From: Stefan O'Rear @ 2020-09-03 11:22 UTC (permalink / raw)
  To: musl; +Cc: Stefan O'Rear

riscv64 and future architectures only provide the clock_ functions.
---
 src/time/clock_gettime.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/src/time/clock_gettime.c b/src/time/clock_gettime.c
index 3e1d0975..c7e66a51 100644
--- a/src/time/clock_gettime.c
+++ b/src/time/clock_gettime.c
@@ -80,10 +80,12 @@ int __clock_gettime(clockid_t clk, struct timespec *ts)
 		return __syscall_ret(r);
 	long ts32[2];
 	r = __syscall(SYS_clock_gettime, clk, ts32);
+#ifdef SYS_gettimeofday
 	if (r==-ENOSYS && clk==CLOCK_REALTIME) {
 		r = __syscall(SYS_gettimeofday, ts32, 0);
 		ts32[1] *= 1000;
 	}
+#endif
 	if (!r) {
 		ts->tv_sec = ts32[0];
 		ts->tv_nsec = ts32[1];
@@ -92,6 +94,7 @@ int __clock_gettime(clockid_t clk, struct timespec *ts)
 	return __syscall_ret(r);
 #else
 	r = __syscall(SYS_clock_gettime, clk, ts);
+#ifdef SYS_gettimeofday
 	if (r == -ENOSYS) {
 		if (clk == CLOCK_REALTIME) {
 			__syscall(SYS_gettimeofday, ts, 0);
@@ -100,6 +103,7 @@ int __clock_gettime(clockid_t clk, struct timespec *ts)
 		}
 		r = -EINVAL;
 	}
+#endif
 	return __syscall_ret(r);
 #endif
 }
-- 
2.25.4


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

* [musl] [PATCH 05/14] Add src/internal/statx.h
  2020-09-03 11:22 [musl] [PATCH 00/14] riscv32 support Stefan O'Rear
                   ` (3 preceding siblings ...)
  2020-09-03 11:22 ` [musl] [PATCH 04/14] time64: Only gettimeofday/settimeofday if exist Stefan O'Rear
@ 2020-09-03 11:23 ` Stefan O'Rear
  2020-09-03 15:39   ` Arnd Bergmann
  2020-09-03 11:23 ` [musl] [PATCH 06/14] Only call fstatat if defined Stefan O'Rear
                   ` (8 subsequent siblings)
  13 siblings, 1 reply; 31+ messages in thread
From: Stefan O'Rear @ 2020-09-03 11:23 UTC (permalink / raw)
  To: musl; +Cc: Stefan O'Rear

We need to make internal syscalls to SYS_statx when SYS_fstatat is not
available without changing the musl API.
---
 src/internal/statx.h | 28 ++++++++++++++++++++++++++++
 src/stat/fstatat.c   | 28 ++--------------------------
 2 files changed, 30 insertions(+), 26 deletions(-)
 create mode 100644 src/internal/statx.h

diff --git a/src/internal/statx.h b/src/internal/statx.h
new file mode 100644
index 00000000..46b16f62
--- /dev/null
+++ b/src/internal/statx.h
@@ -0,0 +1,28 @@
+struct statx {
+	uint32_t stx_mask;
+	uint32_t stx_blksize;
+	uint64_t stx_attributes;
+	uint32_t stx_nlink;
+	uint32_t stx_uid;
+	uint32_t stx_gid;
+	uint16_t stx_mode;
+	uint16_t pad1;
+	uint64_t stx_ino;
+	uint64_t stx_size;
+	uint64_t stx_blocks;
+	uint64_t stx_attributes_mask;
+	struct {
+		int64_t tv_sec;
+		uint32_t tv_nsec;
+		int32_t pad;
+	} stx_atime, stx_btime, stx_ctime, stx_mtime;
+	uint32_t stx_rdev_major;
+	uint32_t stx_rdev_minor;
+	uint32_t stx_dev_major;
+	uint32_t stx_dev_minor;
+	uint64_t spare[14];
+};
+
+#define STATX_TYPE         0x001U
+#define STATX_SIZE         0x200U
+#define STATX_BASIC_STATS  0x7ffU
diff --git a/src/stat/fstatat.c b/src/stat/fstatat.c
index de165b5c..230a83fc 100644
--- a/src/stat/fstatat.c
+++ b/src/stat/fstatat.c
@@ -7,37 +7,13 @@
 #include <sys/sysmacros.h>
 #include "syscall.h"
 #include "kstat.h"
-
-struct statx {
-	uint32_t stx_mask;
-	uint32_t stx_blksize;
-	uint64_t stx_attributes;
-	uint32_t stx_nlink;
-	uint32_t stx_uid;
-	uint32_t stx_gid;
-	uint16_t stx_mode;
-	uint16_t pad1;
-	uint64_t stx_ino;
-	uint64_t stx_size;
-	uint64_t stx_blocks;
-	uint64_t stx_attributes_mask;
-	struct {
-		int64_t tv_sec;
-		uint32_t tv_nsec;
-		int32_t pad;
-	} stx_atime, stx_btime, stx_ctime, stx_mtime;
-	uint32_t stx_rdev_major;
-	uint32_t stx_rdev_minor;
-	uint32_t stx_dev_major;
-	uint32_t stx_dev_minor;
-	uint64_t spare[14];
-};
+#include "statx.h"
 
 static int fstatat_statx(int fd, const char *restrict path, struct stat *restrict st, int flag)
 {
 	struct statx stx;
 
-	int ret = __syscall(SYS_statx, fd, path, flag, 0x7ff, &stx);
+	int ret = __syscall(SYS_statx, fd, path, flag, STATX_BASIC_STATS, &stx);
 	if (ret) return ret;
 
 	*st = (struct stat){
-- 
2.25.4


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

* [musl] [PATCH 06/14] Only call fstatat if defined
  2020-09-03 11:22 [musl] [PATCH 00/14] riscv32 support Stefan O'Rear
                   ` (4 preceding siblings ...)
  2020-09-03 11:23 ` [musl] [PATCH 05/14] Add src/internal/statx.h Stefan O'Rear
@ 2020-09-03 11:23 ` Stefan O'Rear
  2020-09-03 16:05   ` Rich Felker
  2020-09-03 11:23 ` [musl] [PATCH 07/14] Emulate wait4 using waitid Stefan O'Rear
                   ` (7 subsequent siblings)
  13 siblings, 1 reply; 31+ messages in thread
From: Stefan O'Rear @ 2020-09-03 11:23 UTC (permalink / raw)
  To: musl; +Cc: Stefan O'Rear

riscv32 and future architectures lack it.
---
 src/stat/fchmodat.c   | 22 +++++++++++++++++++++-
 src/stat/fstatat.c    |  6 ++++++
 src/stdio/tempnam.c   |  7 +++++++
 src/stdio/tmpnam.c    |  7 +++++++
 src/time/__map_file.c | 13 ++++++++++++-
 5 files changed, 53 insertions(+), 2 deletions(-)

diff --git a/src/stat/fchmodat.c b/src/stat/fchmodat.c
index 4ee00b0a..bcd44cc8 100644
--- a/src/stat/fchmodat.c
+++ b/src/stat/fchmodat.c
@@ -1,8 +1,10 @@
 #include <sys/stat.h>
 #include <fcntl.h>
 #include <errno.h>
+#include <stdint.h>
 #include "syscall.h"
 #include "kstat.h"
+#include "statx.h"
 
 int fchmodat(int fd, const char *path, mode_t mode, int flag)
 {
@@ -11,14 +13,24 @@ int fchmodat(int fd, const char *path, mode_t mode, int flag)
 	if (flag != AT_SYMLINK_NOFOLLOW)
 		return __syscall_ret(-EINVAL);
 
-	struct kstat st;
 	int ret, fd2;
 	char proc[15+3*sizeof(int)];
 
+#ifdef SYS_fstatat
+	struct kstat st;
 	if ((ret = __syscall(SYS_fstatat, fd, path, &st, flag)))
 		return __syscall_ret(ret);
+
 	if (S_ISLNK(st.st_mode))
 		return __syscall_ret(-EOPNOTSUPP);
+#else
+	struct statx st;
+	if ((ret = __syscall(SYS_statx, fd, path, flag, STATX_TYPE, &st)))
+		return __syscall_ret(ret);
+
+	if (S_ISLNK(st.stx_mode))
+		return __syscall_ret(-EOPNOTSUPP);
+#endif
 
 	if ((fd2 = __syscall(SYS_openat, fd, path, O_RDONLY|O_PATH|O_NOFOLLOW|O_NOCTTY|O_CLOEXEC)) < 0) {
 		if (fd2 == -ELOOP)
@@ -27,11 +39,19 @@ int fchmodat(int fd, const char *path, mode_t mode, int flag)
 	}
 
 	__procfdname(proc, fd2);
+#ifdef SYS_fstatat
 	ret = __syscall(SYS_fstatat, AT_FDCWD, proc, &st, 0);
 	if (!ret) {
 		if (S_ISLNK(st.st_mode)) ret = -EOPNOTSUPP;
 		else ret = __syscall(SYS_fchmodat, AT_FDCWD, proc, mode);
 	}
+#else
+	ret = __syscall(SYS_statx, AT_FDCWD, proc, 0, STATX_TYPE, &st);
+	if (!ret) {
+		if (S_ISLNK(st.stx_mode)) ret = -EOPNOTSUPP;
+		else ret = __syscall(SYS_fchmodat, AT_FDCWD, proc, mode);
+	}
+#endif
 
 	__syscall(SYS_close, fd2);
 	return __syscall_ret(ret);
diff --git a/src/stat/fstatat.c b/src/stat/fstatat.c
index 230a83fc..0486f21a 100644
--- a/src/stat/fstatat.c
+++ b/src/stat/fstatat.c
@@ -45,6 +45,7 @@ static int fstatat_statx(int fd, const char *restrict path, struct stat *restric
 	return 0;
 }
 
+#ifdef SYS_fstatat
 static int fstatat_kstat(int fd, const char *restrict path, struct stat *restrict st, int flag)
 {
 	int ret;
@@ -106,15 +107,20 @@ static int fstatat_kstat(int fd, const char *restrict path, struct stat *restric
 
 	return 0;
 }
+#endif
 
 int fstatat(int fd, const char *restrict path, struct stat *restrict st, int flag)
 {
 	int ret;
+#ifdef SYS_fstatat
 	if (sizeof((struct kstat){0}.st_atime_sec) < sizeof(time_t)) {
 		ret = fstatat_statx(fd, path, st, flag);
 		if (ret!=-ENOSYS) return __syscall_ret(ret);
 	}
 	ret = fstatat_kstat(fd, path, st, flag);
+#else
+	ret = fstatat_statx(fd, path, st, flag);
+#endif
 	return __syscall_ret(ret);
 }
 
diff --git a/src/stdio/tempnam.c b/src/stdio/tempnam.c
index 565df6b6..023ff422 100644
--- a/src/stdio/tempnam.c
+++ b/src/stdio/tempnam.c
@@ -5,8 +5,10 @@
 #include <limits.h>
 #include <string.h>
 #include <stdlib.h>
+#include <stdint.h>
 #include "syscall.h"
 #include "kstat.h"
+#include "statx.h"
 
 #define MAXTRIES 100
 
@@ -40,8 +42,13 @@ char *tempnam(const char *dir, const char *pfx)
 #ifdef SYS_lstat
 		r = __syscall(SYS_lstat, s, &(struct kstat){0});
 #else
+#ifdef SYS_fstatat
 		r = __syscall(SYS_fstatat, AT_FDCWD, s,
 			&(struct kstat){0}, AT_SYMLINK_NOFOLLOW);
+#else
+		r = __syscall(SYS_statx, AT_FDCWD, s, AT_SYMLINK_NOFOLLOW, 0,
+			&(struct statx){0});
+#endif
 #endif
 		if (r == -ENOENT) return strdup(s);
 	}
diff --git a/src/stdio/tmpnam.c b/src/stdio/tmpnam.c
index d667a836..c63dabcb 100644
--- a/src/stdio/tmpnam.c
+++ b/src/stdio/tmpnam.c
@@ -4,8 +4,10 @@
 #include <sys/stat.h>
 #include <string.h>
 #include <stdlib.h>
+#include <stdint.h>
 #include "syscall.h"
 #include "kstat.h"
+#include "statx.h"
 
 #define MAXTRIES 100
 
@@ -20,8 +22,13 @@ char *tmpnam(char *buf)
 #ifdef SYS_lstat
 		r = __syscall(SYS_lstat, s, &(struct kstat){0});
 #else
+#ifdef SYS_fstatat
 		r = __syscall(SYS_fstatat, AT_FDCWD, s,
 			&(struct kstat){0}, AT_SYMLINK_NOFOLLOW);
+#else
+		r = __syscall(SYS_statx, AT_FDCWD, s, AT_SYMLINK_NOFOLLOW, 0,
+			&(struct statx){0});
+#endif
 #endif
 		if (r == -ENOENT) return strcpy(buf ? buf : internal, s);
 	}
diff --git a/src/time/__map_file.c b/src/time/__map_file.c
index d3cefa82..f80752bc 100644
--- a/src/time/__map_file.c
+++ b/src/time/__map_file.c
@@ -1,19 +1,30 @@
+#define _BSD_SOURCE
 #include <sys/mman.h>
 #include <fcntl.h>
 #include <sys/stat.h>
+#include <stdint.h>
 #include "syscall.h"
 #include "kstat.h"
+#include "statx.h"
 
 const char unsigned *__map_file(const char *pathname, size_t *size)
 {
-	struct kstat st;
 	const unsigned char *map = MAP_FAILED;
 	int fd = sys_open(pathname, O_RDONLY|O_CLOEXEC|O_NONBLOCK);
 	if (fd < 0) return 0;
+#ifdef SYS_fstat
+	struct kstat st;
 	if (!syscall(SYS_fstat, fd, &st)) {
 		map = __mmap(0, st.st_size, PROT_READ, MAP_SHARED, fd, 0);
 		*size = st.st_size;
 	}
+#else
+	struct statx st;
+	if (!syscall(SYS_statx, fd, "", AT_EMPTY_PATH, STATX_SIZE, &st)) {
+		map = __mmap(0, st.stx_size, PROT_READ, MAP_SHARED, fd, 0);
+		*size = st.stx_size;
+	}
+#endif
 	__syscall(SYS_close, fd);
 	return map == MAP_FAILED ? 0 : map;
 }
-- 
2.25.4


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

* [musl] [PATCH 07/14] Emulate wait4 using waitid
  2020-09-03 11:22 [musl] [PATCH 00/14] riscv32 support Stefan O'Rear
                   ` (5 preceding siblings ...)
  2020-09-03 11:23 ` [musl] [PATCH 06/14] Only call fstatat if defined Stefan O'Rear
@ 2020-09-03 11:23 ` Stefan O'Rear
  2020-09-03 14:56   ` Stefan O'Rear
  2020-09-03 15:49   ` Rich Felker
  2020-09-03 11:23 ` [musl] [PATCH 08/14] riscv: Fall back to syscall __riscv_flush_icache Stefan O'Rear
                   ` (6 subsequent siblings)
  13 siblings, 2 replies; 31+ messages in thread
From: Stefan O'Rear @ 2020-09-03 11:23 UTC (permalink / raw)
  To: musl; +Cc: Stefan O'Rear

riscv32 and future architectures lack wait4.
---
 src/internal/wait4_waitid.h |  1 +
 src/linux/__wait4_waitid.c  | 52 +++++++++++++++++++++++++++++++++++++
 src/linux/wait4.c           |  5 ++++
 src/process/waitpid.c       |  6 +++++
 src/stdio/pclose.c          |  6 +++++
 src/unistd/faccessat.c      |  6 ++++-
 6 files changed, 75 insertions(+), 1 deletion(-)
 create mode 100644 src/internal/wait4_waitid.h
 create mode 100644 src/linux/__wait4_waitid.c

diff --git a/src/internal/wait4_waitid.h b/src/internal/wait4_waitid.h
new file mode 100644
index 00000000..0ef1b9b1
--- /dev/null
+++ b/src/internal/wait4_waitid.h
@@ -0,0 +1 @@
+hidden pid_t __wait4_waitid(pid_t pid, int *status, int options, void *kru, int cp);
diff --git a/src/linux/__wait4_waitid.c b/src/linux/__wait4_waitid.c
new file mode 100644
index 00000000..208f1631
--- /dev/null
+++ b/src/linux/__wait4_waitid.c
@@ -0,0 +1,52 @@
+#include <sys/wait.h>
+#include "syscall.h"
+#include "wait4_waitid.h"
+
+hidden pid_t __wait4_waitid(pid_t pid, int *status, int options, void *kru, int cp)
+{
+	idtype_t t;
+	int r;
+	siginfo_t info;
+
+	info.si_pid = 0;
+	if (pid < -1) {
+		t = P_PGID;
+		pid = -pid;
+	} else if (pid == -1) {
+		t = P_ALL;
+	} else if (pid == 0) {
+		t = P_PGID;
+	} else {
+		t = P_PID;
+	}
+
+	if (cp) r = __syscall_cp(SYS_waitid, t, pid, &info, options|WEXITED, kru);
+	else r = __syscall(SYS_waitid, t, pid, &info, options|WEXITED, kru);
+
+	if (r<0) return r;
+
+	if (info.si_pid && status) {
+		int sw=0;
+		switch (info.si_code) {
+		case CLD_CONTINUED:
+			sw = 0xffff;
+			break;
+		case CLD_DUMPED:
+			sw = info.si_status&0x7f | 0x80;
+			break;
+		case CLD_EXITED:
+			sw = (info.si_status&0xff) << 8;
+			break;
+		case CLD_KILLED:
+			sw = info.si_status&0x7f;
+			break;
+		case CLD_STOPPED:
+		case CLD_TRAPPED:
+			sw = ((info.si_status&0xff) << 8) + 0x7f;
+			break;
+		}
+		*status = sw;
+	}
+
+	return info.si_pid;
+}
diff --git a/src/linux/wait4.c b/src/linux/wait4.c
index 83650e34..e4d3a053 100644
--- a/src/linux/wait4.c
+++ b/src/linux/wait4.c
@@ -4,6 +4,7 @@
 #include <string.h>
 #include <errno.h>
 #include "syscall.h"
+#include "wait4_waitid.h"
 
 pid_t wait4(pid_t pid, int *status, int options, struct rusage *ru)
 {
@@ -26,7 +27,11 @@ pid_t wait4(pid_t pid, int *status, int options, struct rusage *ru)
 	}
 #endif
 	char *dest = ru ? (char *)&ru->ru_maxrss - 4*sizeof(long) : 0;
+#ifdef SYS_wait4
 	r = __syscall(SYS_wait4, pid, status, options, dest);
+#else
+	r = __wait4_waitid(pid, status, options, dest, 0);
+#endif
 	if (r>0 && ru && sizeof(time_t) > sizeof(long)) {
 		long kru[4];
 		memcpy(kru, dest, 4*sizeof(long));
diff --git a/src/process/waitpid.c b/src/process/waitpid.c
index 1b65bf05..49668822 100644
--- a/src/process/waitpid.c
+++ b/src/process/waitpid.c
@@ -1,7 +1,13 @@
+#define _GNU_SOURCE
 #include <sys/wait.h>
 #include "syscall.h"
+#include "wait4_waitid.h"
 
 pid_t waitpid(pid_t pid, int *status, int options)
 {
+#ifdef SYS_wait4
 	return syscall_cp(SYS_wait4, pid, status, options, 0);
+#else
+	return __syscall_ret(__wait4_waitid(pid, status, options, 0, 1));
+#endif
 }
diff --git a/src/stdio/pclose.c b/src/stdio/pclose.c
index 080a4262..79e3d1d5 100644
--- a/src/stdio/pclose.c
+++ b/src/stdio/pclose.c
@@ -1,4 +1,6 @@
 #include "stdio_impl.h"
+#include <sys/wait.h>
+#include "wait4_waitid.h"
 #include <errno.h>
 #include <unistd.h>
 
@@ -7,7 +9,11 @@ int pclose(FILE *f)
 	int status, r;
 	pid_t pid = f->pipe_pid;
 	fclose(f);
+#ifdef SYS_wait4
 	while ((r=__syscall(SYS_wait4, pid, &status, 0, 0)) == -EINTR);
+#else
+	while ((r=__wait4_waitid(pid, &status, 0, 0, 0)) == -EINTR);
+#endif
 	if (r<0) return __syscall_ret(r);
 	return status;
 }
diff --git a/src/unistd/faccessat.c b/src/unistd/faccessat.c
index 76bbd4c7..8bf34995 100644
--- a/src/unistd/faccessat.c
+++ b/src/unistd/faccessat.c
@@ -34,7 +34,6 @@ int faccessat(int fd, const char *filename, int amode, int flag)
 	char stack[1024];
 	sigset_t set;
 	pid_t pid;
-	int status;
 	int ret, p[2];
 
 	if (pipe2(p, O_CLOEXEC)) return __syscall_ret(-EBUSY);
@@ -48,7 +47,12 @@ int faccessat(int fd, const char *filename, int amode, int flag)
 	if (pid<0 || __syscall(SYS_read, p[0], &ret, sizeof ret) != sizeof(ret))
 		ret = -EBUSY;
 	__syscall(SYS_close, p[0]);
+#ifdef SYS_wait4
+	int status;
 	__syscall(SYS_wait4, pid, &status, __WCLONE, 0);
+#else
+	__syscall(SYS_waitid, P_PID, pid, &(siginfo_t){0}, __WCLONE|WEXITED, 0);
+#endif
 
 	__restore_sigs(&set);
 
-- 
2.25.4


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

* [musl] [PATCH 08/14] riscv: Fall back to syscall __riscv_flush_icache
  2020-09-03 11:22 [musl] [PATCH 00/14] riscv32 support Stefan O'Rear
                   ` (6 preceding siblings ...)
  2020-09-03 11:23 ` [musl] [PATCH 07/14] Emulate wait4 using waitid Stefan O'Rear
@ 2020-09-03 11:23 ` Stefan O'Rear
  2020-09-03 11:23 ` [musl] [PATCH 09/14] riscv32: Target and subtarget detection Stefan O'Rear
                   ` (5 subsequent siblings)
  13 siblings, 0 replies; 31+ messages in thread
From: Stefan O'Rear @ 2020-09-03 11:23 UTC (permalink / raw)
  To: musl; +Cc: Stefan O'Rear

Matches glibc behavior and fixes a case where we could fall off the
function without returning a value.
---
 src/linux/cache.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/linux/cache.c b/src/linux/cache.c
index 0eb051c2..9cacac2b 100644
--- a/src/linux/cache.c
+++ b/src/linux/cache.c
@@ -45,6 +45,7 @@ int __riscv_flush_icache(void *start, void *end, unsigned long int flags)
 		if (!r) return r;
 		if (r != -ENOSYS) return __syscall_ret(r);
 	}
+	return syscall(SYS_riscv_flush_icache, start, end, flags);
 }
 weak_alias(__riscv_flush_icache, riscv_flush_icache);
 #endif
-- 
2.25.4


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

* [musl] [PATCH 09/14] riscv32: Target and subtarget detection
  2020-09-03 11:22 [musl] [PATCH 00/14] riscv32 support Stefan O'Rear
                   ` (7 preceding siblings ...)
  2020-09-03 11:23 ` [musl] [PATCH 08/14] riscv: Fall back to syscall __riscv_flush_icache Stefan O'Rear
@ 2020-09-03 11:23 ` Stefan O'Rear
  2020-09-03 11:23 ` [musl] [PATCH 10/14] riscv32: add arch headers Stefan O'Rear
                   ` (4 subsequent siblings)
  13 siblings, 0 replies; 31+ messages in thread
From: Stefan O'Rear @ 2020-09-03 11:23 UTC (permalink / raw)
  To: musl; +Cc: Stefan O'Rear

---
 configure | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/configure b/configure
index 49a7b403..346080ce 100755
--- a/configure
+++ b/configure
@@ -336,6 +336,7 @@ or1k*) ARCH=or1k ;;
 powerpc64*|ppc64*) ARCH=powerpc64 ;;
 powerpc*|ppc*) ARCH=powerpc ;;
 riscv64*) ARCH=riscv64 ;;
+riscv32*) ARCH=riscv32 ;;
 sh[1-9bel-]*|sh|superh*) ARCH=sh ;;
 s390x*) ARCH=s390x ;;
 unknown) fail "$0: unable to detect target arch; try $0 --target=..." ;;
@@ -694,7 +695,7 @@ trycppif __LITTLE_ENDIAN__ "$t" && SUBARCH=${SUBARCH}le
 trycppif _SOFT_FLOAT "$t" && fail "$0: error: soft-float not supported on powerpc64"
 fi
 
-if test "$ARCH" = "riscv64" ; then
+if test "$ARCH" = "riscv64" -o "$ARCH" = "riscv32" ; then
 trycppif __riscv_float_abi_soft "$t" && SUBARCH=${SUBARCH}-sf
 trycppif __riscv_float_abi_single "$t" && SUBARCH=${SUBARCH}-sp
 fi
-- 
2.25.4


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

* [musl] [PATCH 10/14] riscv32: add arch headers
  2020-09-03 11:22 [musl] [PATCH 00/14] riscv32 support Stefan O'Rear
                   ` (8 preceding siblings ...)
  2020-09-03 11:23 ` [musl] [PATCH 09/14] riscv32: Target and subtarget detection Stefan O'Rear
@ 2020-09-03 11:23 ` Stefan O'Rear
  2020-09-03 15:49   ` Arnd Bergmann
  2020-09-03 11:23 ` [musl] [PATCH 11/14] riscv32: Add fenv and math Stefan O'Rear
                   ` (3 subsequent siblings)
  13 siblings, 1 reply; 31+ messages in thread
From: Stefan O'Rear @ 2020-09-03 11:23 UTC (permalink / raw)
  To: musl; +Cc: Stefan O'Rear

These are mostly copied from riscv64.  _Addr and _Reg had to become int
to avoid errors in libstdc++ when size_t and std::size_t mismatch.
There is no kernel stat struct; the userspace stat matches glibc in the
sizes and offsets of all fields (including glibc's __dev_t __pad1).  The
jump buffer is 12 words larger to account for 12 saved double-precision
floats; additionally it should be 64-bit aligned to save doubles.

The syscall list was significantly revised by deleting all time32 and
pre-statx syscalls, and renaming several syscalls that have different
names depending on __BITS_PER_LONG, notably mmap2 and _llseek.
---
 arch/riscv32/atomic_arch.h      |  21 +++
 arch/riscv32/bits/alltypes.h.in |  18 ++
 arch/riscv32/bits/fcntl.h       |  38 +++++
 arch/riscv32/bits/fenv.h        |  17 ++
 arch/riscv32/bits/float.h       |  16 ++
 arch/riscv32/bits/posix.h       |   2 +
 arch/riscv32/bits/setjmp.h      |   1 +
 arch/riscv32/bits/signal.h      | 118 +++++++++++++
 arch/riscv32/bits/stat.h        |  18 ++
 arch/riscv32/bits/stdint.h      |  20 +++
 arch/riscv32/bits/syscall.h.in  | 284 ++++++++++++++++++++++++++++++++
 arch/riscv32/bits/user.h        |   5 +
 arch/riscv32/crt_arch.h         |  19 +++
 arch/riscv32/kstat.h            |   0
 arch/riscv32/pthread_arch.h     |  13 ++
 arch/riscv32/reloc.h            |  22 +++
 arch/riscv32/syscall_arch.h     |  78 +++++++++
 17 files changed, 690 insertions(+)
 create mode 100644 arch/riscv32/atomic_arch.h
 create mode 100644 arch/riscv32/bits/alltypes.h.in
 create mode 100644 arch/riscv32/bits/fcntl.h
 create mode 100644 arch/riscv32/bits/fenv.h
 create mode 100644 arch/riscv32/bits/float.h
 create mode 100644 arch/riscv32/bits/posix.h
 create mode 100644 arch/riscv32/bits/setjmp.h
 create mode 100644 arch/riscv32/bits/signal.h
 create mode 100644 arch/riscv32/bits/stat.h
 create mode 100644 arch/riscv32/bits/stdint.h
 create mode 100644 arch/riscv32/bits/syscall.h.in
 create mode 100644 arch/riscv32/bits/user.h
 create mode 100644 arch/riscv32/crt_arch.h
 create mode 100644 arch/riscv32/kstat.h
 create mode 100644 arch/riscv32/pthread_arch.h
 create mode 100644 arch/riscv32/reloc.h
 create mode 100644 arch/riscv32/syscall_arch.h

diff --git a/arch/riscv32/atomic_arch.h b/arch/riscv32/atomic_arch.h
new file mode 100644
index 00000000..4d418f63
--- /dev/null
+++ b/arch/riscv32/atomic_arch.h
@@ -0,0 +1,21 @@
+#define a_barrier a_barrier
+static inline void a_barrier()
+{
+	__asm__ __volatile__ ("fence rw,rw" : : : "memory");
+}
+
+#define a_cas a_cas
+static inline int a_cas(volatile int *p, int t, int s)
+{
+	int old, tmp;
+	__asm__ __volatile__ (
+		"\n1:	lr.w.aqrl %0, (%2)\n"
+		"	bne %0, %3, 1f\n"
+		"	sc.w.aqrl %1, %4, (%2)\n"
+		"	bnez %1, 1b\n"
+		"1:"
+		: "=&r"(old), "=&r"(tmp)
+		: "r"(p), "r"((long)t), "r"((long)s)
+		: "memory");
+	return old;
+}
diff --git a/arch/riscv32/bits/alltypes.h.in b/arch/riscv32/bits/alltypes.h.in
new file mode 100644
index 00000000..e2b6129e
--- /dev/null
+++ b/arch/riscv32/bits/alltypes.h.in
@@ -0,0 +1,18 @@
+#define _Addr int
+#define _Int64 long long
+#define _Reg int
+
+#define __BYTE_ORDER 1234
+#define __LONG_MAX 0x7fffffffL
+
+#ifndef __cplusplus
+TYPEDEF int wchar_t;
+#endif
+
+TYPEDEF int blksize_t;
+TYPEDEF unsigned int nlink_t;
+
+TYPEDEF float float_t;
+TYPEDEF double double_t;
+
+TYPEDEF struct { long long __ll; long double __ld; } max_align_t;
diff --git a/arch/riscv32/bits/fcntl.h b/arch/riscv32/bits/fcntl.h
new file mode 100644
index 00000000..ecb4d18f
--- /dev/null
+++ b/arch/riscv32/bits/fcntl.h
@@ -0,0 +1,38 @@
+#define O_CREAT        0100
+#define O_EXCL         0200
+#define O_NOCTTY       0400
+#define O_TRUNC       01000
+#define O_APPEND      02000
+#define O_NONBLOCK    04000
+#define O_DSYNC      010000
+#define O_SYNC     04010000
+#define O_RSYNC    04010000
+#define O_DIRECTORY 0200000
+#define O_NOFOLLOW  0400000
+#define O_CLOEXEC  02000000
+
+#define O_ASYNC      020000
+#define O_DIRECT     040000
+#define O_LARGEFILE 0100000
+#define O_NOATIME  01000000
+#define O_PATH    010000000
+#define O_TMPFILE 020200000
+#define O_NDELAY O_NONBLOCK
+
+#define F_DUPFD  0
+#define F_GETFD  1
+#define F_SETFD  2
+#define F_GETFL  3
+#define F_SETFL  4
+#define F_GETLK  5
+#define F_SETLK  6
+#define F_SETLKW 7
+#define F_SETOWN 8
+#define F_GETOWN 9
+#define F_SETSIG 10
+#define F_GETSIG 11
+
+#define F_SETOWN_EX 15
+#define F_GETOWN_EX 16
+
+#define F_GETOWNER_UIDS 17
diff --git a/arch/riscv32/bits/fenv.h b/arch/riscv32/bits/fenv.h
new file mode 100644
index 00000000..806ec40f
--- /dev/null
+++ b/arch/riscv32/bits/fenv.h
@@ -0,0 +1,17 @@
+#define FE_INVALID      16
+#define FE_DIVBYZERO    8
+#define FE_OVERFLOW     4
+#define FE_UNDERFLOW    2
+#define FE_INEXACT      1
+
+#define FE_ALL_EXCEPT   31
+
+#define FE_TONEAREST    0
+#define FE_DOWNWARD     2
+#define FE_UPWARD       3
+#define FE_TOWARDZERO   1
+
+typedef unsigned int fexcept_t;
+typedef unsigned int fenv_t;
+
+#define FE_DFL_ENV      ((const fenv_t *) -1)
diff --git a/arch/riscv32/bits/float.h b/arch/riscv32/bits/float.h
new file mode 100644
index 00000000..719c7908
--- /dev/null
+++ b/arch/riscv32/bits/float.h
@@ -0,0 +1,16 @@
+#define FLT_EVAL_METHOD 0
+
+#define LDBL_TRUE_MIN 6.47517511943802511092443895822764655e-4966L
+#define LDBL_MIN 3.36210314311209350626267781732175260e-4932L
+#define LDBL_MAX 1.18973149535723176508575932662800702e+4932L
+#define LDBL_EPSILON 1.92592994438723585305597794258492732e-34L
+
+#define LDBL_MANT_DIG 113
+#define LDBL_MIN_EXP (-16381)
+#define LDBL_MAX_EXP 16384
+
+#define LDBL_DIG 33
+#define LDBL_MIN_10_EXP (-4931)
+#define LDBL_MAX_10_EXP 4932
+
+#define DECIMAL_DIG 36
diff --git a/arch/riscv32/bits/posix.h b/arch/riscv32/bits/posix.h
new file mode 100644
index 00000000..8897d37d
--- /dev/null
+++ b/arch/riscv32/bits/posix.h
@@ -0,0 +1,2 @@
+#define _POSIX_V6_ILP32_OFFBIG 1
+#define _POSIX_V7_ILP32_OFFBIG 1
diff --git a/arch/riscv32/bits/setjmp.h b/arch/riscv32/bits/setjmp.h
new file mode 100644
index 00000000..51e96276
--- /dev/null
+++ b/arch/riscv32/bits/setjmp.h
@@ -0,0 +1 @@
+typedef unsigned long long __jmp_buf[19];
diff --git a/arch/riscv32/bits/signal.h b/arch/riscv32/bits/signal.h
new file mode 100644
index 00000000..b006334f
--- /dev/null
+++ b/arch/riscv32/bits/signal.h
@@ -0,0 +1,118 @@
+#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
+
+typedef unsigned long __riscv_mc_gp_state[32];
+
+struct __riscv_mc_f_ext_state {
+	unsigned int __f[32];
+	unsigned int __fcsr;
+};
+
+struct __riscv_mc_d_ext_state {
+	unsigned long long __f[32];
+	unsigned int __fcsr;
+};
+
+struct __riscv_mc_q_ext_state {
+	unsigned long long __f[64] __attribute__((aligned(16)));
+	unsigned int __fcsr;
+	unsigned int __reserved[3];
+};
+
+union __riscv_mc_fp_state {
+	struct __riscv_mc_f_ext_state __f;
+	struct __riscv_mc_d_ext_state __d;
+	struct __riscv_mc_q_ext_state __q;
+};
+
+typedef struct mcontext_t {
+	__riscv_mc_gp_state __gregs;
+	union __riscv_mc_fp_state __fpregs;
+} mcontext_t;
+
+#if defined(_GNU_SOURCE)
+#define REG_PC 0
+#define REG_RA 1
+#define REG_SP 2
+#define REG_TP 4
+#define REG_S0 8
+#define REG_A0 10
+#endif
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+typedef unsigned long greg_t;
+typedef unsigned long gregset_t[32];
+typedef union __riscv_mc_fp_state fpregset_t;
+struct sigcontext {
+	gregset_t gregs;
+	fpregset_t fpregs;
+};
+#endif
+
+struct sigaltstack {
+	void *ss_sp;
+	int ss_flags;
+	size_t ss_size;
+};
+
+typedef struct ucontext_t
+{
+	unsigned long uc_flags;
+	struct ucontext_t *uc_link;
+	stack_t uc_stack;
+	sigset_t uc_sigmask;
+	mcontext_t uc_mcontext;
+} 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   SIGIO
+#define SIGPWR    30
+#define SIGSYS    31
+#define SIGUNUSED SIGSYS
+
+#define _NSIG     65
diff --git a/arch/riscv32/bits/stat.h b/arch/riscv32/bits/stat.h
new file mode 100644
index 00000000..f6d9e864
--- /dev/null
+++ b/arch/riscv32/bits/stat.h
@@ -0,0 +1,18 @@
+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;
+	unsigned long long __pad;
+	off_t st_size;
+	blksize_t st_blksize;
+	int __pad2;
+	blkcnt_t st_blocks;
+	struct timespec st_atim;
+	struct timespec st_mtim;
+	struct timespec st_ctim;
+	unsigned __unused[2];
+};
diff --git a/arch/riscv32/bits/stdint.h b/arch/riscv32/bits/stdint.h
new file mode 100644
index 00000000..d1b27121
--- /dev/null
+++ b/arch/riscv32/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/riscv32/bits/syscall.h.in b/arch/riscv32/bits/syscall.h.in
new file mode 100644
index 00000000..08131e64
--- /dev/null
+++ b/arch/riscv32/bits/syscall.h.in
@@ -0,0 +1,284 @@
+#define __NR_io_setup 0
+#define __NR_io_destroy 1
+#define __NR_io_submit 2
+#define __NR_io_cancel 3
+#define __NR_setxattr 5
+#define __NR_lsetxattr 6
+#define __NR_fsetxattr 7
+#define __NR_getxattr 8
+#define __NR_lgetxattr 9
+#define __NR_fgetxattr 10
+#define __NR_listxattr 11
+#define __NR_llistxattr 12
+#define __NR_flistxattr 13
+#define __NR_removexattr 14
+#define __NR_lremovexattr 15
+#define __NR_fremovexattr 16
+#define __NR_getcwd 17
+#define __NR_lookup_dcookie 18
+#define __NR_eventfd2 19
+#define __NR_epoll_create1 20
+#define __NR_epoll_ctl 21
+#define __NR_epoll_pwait 22
+#define __NR_dup 23
+#define __NR_dup3 24
+#define __NR_fcntl64 25
+#define __NR_inotify_init1 26
+#define __NR_inotify_add_watch 27
+#define __NR_inotify_rm_watch 28
+#define __NR_ioctl 29
+#define __NR_ioprio_set 30
+#define __NR_ioprio_get 31
+#define __NR_flock 32
+#define __NR_mknodat 33
+#define __NR_mkdirat 34
+#define __NR_unlinkat 35
+#define __NR_symlinkat 36
+#define __NR_linkat 37
+#define __NR_umount2 39
+#define __NR_mount 40
+#define __NR_pivot_root 41
+#define __NR_nfsservctl 42
+#define __NR_statfs64 43
+#define __NR_fstatfs64 44
+#define __NR_truncate64 45
+#define __NR_ftruncate64 46
+#define __NR_fallocate 47
+#define __NR_faccessat 48
+#define __NR_chdir 49
+#define __NR_fchdir 50
+#define __NR_chroot 51
+#define __NR_fchmod 52
+#define __NR_fchmodat 53
+#define __NR_fchownat 54
+#define __NR_fchown 55
+#define __NR_openat 56
+#define __NR_close 57
+#define __NR_vhangup 58
+#define __NR_pipe2 59
+#define __NR_quotactl 60
+#define __NR_getdents64 61
+#define __NR__llseek 62
+#define __NR_read 63
+#define __NR_write 64
+#define __NR_readv 65
+#define __NR_writev 66
+#define __NR_pread64 67
+#define __NR_pwrite64 68
+#define __NR_preadv 69
+#define __NR_pwritev 70
+#define __NR_sendfile64 71
+#define __NR_signalfd4 74
+#define __NR_vmsplice 75
+#define __NR_splice 76
+#define __NR_tee 77
+#define __NR_readlinkat 78
+#define __NR_sync 81
+#define __NR_fsync 82
+#define __NR_fdatasync 83
+#define __NR_sync_file_range 84
+#define __NR_timerfd_create 85
+#define __NR_acct 89
+#define __NR_capget 90
+#define __NR_capset 91
+#define __NR_personality 92
+#define __NR_exit 93
+#define __NR_exit_group 94
+#define __NR_waitid 95
+#define __NR_set_tid_address 96
+#define __NR_unshare 97
+#define __NR_set_robust_list 99
+#define __NR_get_robust_list 100
+#define __NR_nanosleep 101
+#define __NR_getitimer 102
+#define __NR_setitimer 103
+#define __NR_kexec_load 104
+#define __NR_init_module 105
+#define __NR_delete_module 106
+#define __NR_timer_create 107
+#define __NR_timer_getoverrun 109
+#define __NR_timer_delete 111
+#define __NR_syslog 116
+#define __NR_ptrace 117
+#define __NR_sched_setparam 118
+#define __NR_sched_setscheduler 119
+#define __NR_sched_getscheduler 120
+#define __NR_sched_getparam 121
+#define __NR_sched_setaffinity 122
+#define __NR_sched_getaffinity 123
+#define __NR_sched_yield 124
+#define __NR_sched_get_priority_max 125
+#define __NR_sched_get_priority_min 126
+#define __NR_restart_syscall 128
+#define __NR_kill 129
+#define __NR_tkill 130
+#define __NR_tgkill 131
+#define __NR_sigaltstack 132
+#define __NR_rt_sigsuspend 133
+#define __NR_rt_sigaction 134
+#define __NR_rt_sigprocmask 135
+#define __NR_rt_sigpending 136
+#define __NR_rt_sigqueueinfo 138
+#define __NR_rt_sigreturn 139
+#define __NR_setpriority 140
+#define __NR_getpriority 141
+#define __NR_reboot 142
+#define __NR_setregid 143
+#define __NR_setgid 144
+#define __NR_setreuid 145
+#define __NR_setuid 146
+#define __NR_setresuid 147
+#define __NR_getresuid 148
+#define __NR_setresgid 149
+#define __NR_getresgid 150
+#define __NR_setfsuid 151
+#define __NR_setfsgid 152
+#define __NR_times 153
+#define __NR_setpgid 154
+#define __NR_getpgid 155
+#define __NR_getsid 156
+#define __NR_setsid 157
+#define __NR_getgroups 158
+#define __NR_setgroups 159
+#define __NR_uname 160
+#define __NR_sethostname 161
+#define __NR_setdomainname 162
+#define __NR_getrusage 165
+#define __NR_umask 166
+#define __NR_prctl 167
+#define __NR_getcpu 168
+#define __NR_getpid 172
+#define __NR_getppid 173
+#define __NR_getuid 174
+#define __NR_geteuid 175
+#define __NR_getgid 176
+#define __NR_getegid 177
+#define __NR_gettid 178
+#define __NR_sysinfo 179
+#define __NR_mq_open 180
+#define __NR_mq_unlink 181
+#define __NR_mq_notify 184
+#define __NR_mq_getsetattr 185
+#define __NR_msgget 186
+#define __NR_msgctl 187
+#define __NR_msgrcv 188
+#define __NR_msgsnd 189
+#define __NR_semget 190
+#define __NR_semctl 191
+#define __NR_semop 193
+#define __NR_shmget 194
+#define __NR_shmctl 195
+#define __NR_shmat 196
+#define __NR_shmdt 197
+#define __NR_socket 198
+#define __NR_socketpair 199
+#define __NR_bind 200
+#define __NR_listen 201
+#define __NR_accept 202
+#define __NR_connect 203
+#define __NR_getsockname 204
+#define __NR_getpeername 205
+#define __NR_sendto 206
+#define __NR_recvfrom 207
+#define __NR_setsockopt 208
+#define __NR_getsockopt 209
+#define __NR_shutdown 210
+#define __NR_sendmsg 211
+#define __NR_recvmsg 212
+#define __NR_readahead 213
+#define __NR_brk 214
+#define __NR_munmap 215
+#define __NR_mremap 216
+#define __NR_add_key 217
+#define __NR_request_key 218
+#define __NR_keyctl 219
+#define __NR_clone 220
+#define __NR_execve 221
+#define __NR_mmap2 222
+#define __NR_fadvise64_64 223
+#define __NR_swapon 224
+#define __NR_swapoff 225
+#define __NR_mprotect 226
+#define __NR_msync 227
+#define __NR_mlock 228
+#define __NR_munlock 229
+#define __NR_mlockall 230
+#define __NR_munlockall 231
+#define __NR_mincore 232
+#define __NR_madvise 233
+#define __NR_remap_file_pages 234
+#define __NR_mbind 235
+#define __NR_get_mempolicy 236
+#define __NR_set_mempolicy 237
+#define __NR_migrate_pages 238
+#define __NR_move_pages 239
+#define __NR_rt_tgsigqueueinfo 240
+#define __NR_perf_event_open 241
+#define __NR_accept4 242
+#define __NR_arch_specific_syscall 244
+#define __NR_prlimit64 261
+#define __NR_fanotify_init 262
+#define __NR_fanotify_mark 263
+#define __NR_name_to_handle_at 264
+#define __NR_open_by_handle_at 265
+#define __NR_syncfs 267
+#define __NR_setns 268
+#define __NR_sendmmsg 269
+#define __NR_process_vm_readv 270
+#define __NR_process_vm_writev 271
+#define __NR_kcmp 272
+#define __NR_finit_module 273
+#define __NR_sched_setattr 274
+#define __NR_sched_getattr 275
+#define __NR_renameat2 276
+#define __NR_seccomp 277
+#define __NR_getrandom 278
+#define __NR_memfd_create 279
+#define __NR_bpf 280
+#define __NR_execveat 281
+#define __NR_userfaultfd 282
+#define __NR_membarrier 283
+#define __NR_mlock2 284
+#define __NR_copy_file_range 285
+#define __NR_preadv2 286
+#define __NR_pwritev2 287
+#define __NR_pkey_mprotect 288
+#define __NR_pkey_alloc 289
+#define __NR_pkey_free 290
+#define __NR_statx 291
+#define __NR_rseq 293
+#define __NR_kexec_file_load 294
+#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_sysriscv __NR_arch_specific_syscall
+#define __NR_riscv_flush_icache (__NR_sysriscv + 15)
diff --git a/arch/riscv32/bits/user.h b/arch/riscv32/bits/user.h
new file mode 100644
index 00000000..2da743ea
--- /dev/null
+++ b/arch/riscv32/bits/user.h
@@ -0,0 +1,5 @@
+#include <signal.h>
+
+#define ELF_NGREG 32
+typedef unsigned long elf_greg_t, elf_gregset_t[ELF_NGREG];
+typedef union __riscv_mc_fp_state elf_fpregset_t;
diff --git a/arch/riscv32/crt_arch.h b/arch/riscv32/crt_arch.h
new file mode 100644
index 00000000..6b93fcfd
--- /dev/null
+++ b/arch/riscv32/crt_arch.h
@@ -0,0 +1,19 @@
+__asm__(
+".section .sdata,\"aw\"\n"
+".text\n"
+".global " START "\n"
+".type " START ",%function\n"
+START ":\n"
+".weak __global_pointer$\n"
+".hidden __global_pointer$\n"
+".option push\n"
+".option norelax\n\t"
+"lla gp, __global_pointer$\n"
+".option pop\n\t"
+"mv a0, sp\n"
+".weak _DYNAMIC\n"
+".hidden _DYNAMIC\n\t"
+"lla a1, _DYNAMIC\n\t"
+"andi sp, sp, -16\n\t"
+"tail " START "_c"
+);
diff --git a/arch/riscv32/kstat.h b/arch/riscv32/kstat.h
new file mode 100644
index 00000000..e69de29b
diff --git a/arch/riscv32/pthread_arch.h b/arch/riscv32/pthread_arch.h
new file mode 100644
index 00000000..a20d7fba
--- /dev/null
+++ b/arch/riscv32/pthread_arch.h
@@ -0,0 +1,13 @@
+static inline uintptr_t __get_tp()
+{
+	uintptr_t tp;
+	__asm__ __volatile__("mv %0, tp" : "=r"(tp));
+	return tp;
+}
+
+#define TLS_ABOVE_TP
+#define GAP_ABOVE_TP 0
+
+#define DTP_OFFSET 0x800
+
+#define MC_PC __gregs[0]
diff --git a/arch/riscv32/reloc.h b/arch/riscv32/reloc.h
new file mode 100644
index 00000000..59d15f17
--- /dev/null
+++ b/arch/riscv32/reloc.h
@@ -0,0 +1,22 @@
+#if defined __riscv_float_abi_soft
+#define RISCV_FP_SUFFIX "-sf"
+#elif defined __riscv_float_abi_single
+#define RISCV_FP_SUFFIX "-sp"
+#elif defined __riscv_float_abi_double
+#define RISCV_FP_SUFFIX ""
+#endif
+
+#define LDSO_ARCH "riscv32" RISCV_FP_SUFFIX
+
+#define TPOFF_K 0
+
+#define REL_SYMBOLIC    R_RISCV_32
+#define REL_PLT         R_RISCV_JUMP_SLOT
+#define REL_RELATIVE    R_RISCV_RELATIVE
+#define REL_COPY        R_RISCV_COPY
+#define REL_DTPMOD      R_RISCV_TLS_DTPMOD32
+#define REL_DTPOFF      R_RISCV_TLS_DTPREL32
+#define REL_TPOFF       R_RISCV_TLS_TPREL32
+
+#define CRTJMP(pc,sp) __asm__ __volatile__( \
+	"mv sp, %1 ; jr %0" : : "r"(pc), "r"(sp) : "memory" )
diff --git a/arch/riscv32/syscall_arch.h b/arch/riscv32/syscall_arch.h
new file mode 100644
index 00000000..9e916c76
--- /dev/null
+++ b/arch/riscv32/syscall_arch.h
@@ -0,0 +1,78 @@
+#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) __SYSCALL_LL_E((x))
+
+#define __asm_syscall(...) \
+	__asm__ __volatile__ ("ecall\n\t" \
+	: "=r"(a0) : __VA_ARGS__ : "memory"); \
+	return a0; \
+
+static inline long __syscall0(long n)
+{
+	register long a7 __asm__("a7") = n;
+	register long a0 __asm__("a0");
+	__asm_syscall("r"(a7))
+}
+
+static inline long __syscall1(long n, long a)
+{
+	register long a7 __asm__("a7") = n;
+	register long a0 __asm__("a0") = a;
+	__asm_syscall("r"(a7), "0"(a0))
+}
+
+static inline long __syscall2(long n, long a, long b)
+{
+	register long a7 __asm__("a7") = n;
+	register long a0 __asm__("a0") = a;
+	register long a1 __asm__("a1") = b;
+	__asm_syscall("r"(a7), "0"(a0), "r"(a1))
+}
+
+static inline long __syscall3(long n, long a, long b, long c)
+{
+	register long a7 __asm__("a7") = n;
+	register long a0 __asm__("a0") = a;
+	register long a1 __asm__("a1") = b;
+	register long a2 __asm__("a2") = c;
+	__asm_syscall("r"(a7), "0"(a0), "r"(a1), "r"(a2))
+}
+
+static inline long __syscall4(long n, long a, long b, long c, long d)
+{
+	register long a7 __asm__("a7") = n;
+	register long a0 __asm__("a0") = a;
+	register long a1 __asm__("a1") = b;
+	register long a2 __asm__("a2") = c;
+	register long a3 __asm__("a3") = d;
+	__asm_syscall("r"(a7), "0"(a0), "r"(a1), "r"(a2), "r"(a3))
+}
+
+static inline long __syscall5(long n, long a, long b, long c, long d, long e)
+{
+	register long a7 __asm__("a7") = n;
+	register long a0 __asm__("a0") = a;
+	register long a1 __asm__("a1") = b;
+	register long a2 __asm__("a2") = c;
+	register long a3 __asm__("a3") = d;
+	register long a4 __asm__("a4") = e;
+	__asm_syscall("r"(a7), "0"(a0), "r"(a1), "r"(a2), "r"(a3), "r"(a4))
+}
+
+static inline long __syscall6(long n, long a, long b, long c, long d, long e, long f)
+{
+	register long a7 __asm__("a7") = n;
+	register long a0 __asm__("a0") = a;
+	register long a1 __asm__("a1") = b;
+	register long a2 __asm__("a2") = c;
+	register long a3 __asm__("a3") = d;
+	register long a4 __asm__("a4") = e;
+	register long a5 __asm__("a5") = f;
+	__asm_syscall("r"(a7), "0"(a0), "r"(a1), "r"(a2), "r"(a3), "r"(a4), "r"(a5))
+}
+
+#define VDSO_USEFUL
+/* We don't have a clock_gettime function.
+#define VDSO_CGT_SYM "__vdso_clock_gettime"
+#define VDSO_CGT_VER "LINUX_2.6" */
-- 
2.25.4


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

* [musl] [PATCH 11/14] riscv32: Add fenv and math
  2020-09-03 11:22 [musl] [PATCH 00/14] riscv32 support Stefan O'Rear
                   ` (9 preceding siblings ...)
  2020-09-03 11:23 ` [musl] [PATCH 10/14] riscv32: add arch headers Stefan O'Rear
@ 2020-09-03 11:23 ` Stefan O'Rear
  2020-09-03 11:23 ` [musl] [PATCH 12/14] riscv32: Add dlsym Stefan O'Rear
                   ` (2 subsequent siblings)
  13 siblings, 0 replies; 31+ messages in thread
From: Stefan O'Rear @ 2020-09-03 11:23 UTC (permalink / raw)
  To: musl; +Cc: Stefan O'Rear

These are identical to riscv64.
---
 src/fenv/riscv32/fenv-sf.c   |  3 ++
 src/fenv/riscv32/fenv.S      | 56 ++++++++++++++++++++++++++++++++++++
 src/math/riscv32/copysign.c  | 15 ++++++++++
 src/math/riscv32/copysignf.c | 15 ++++++++++
 src/math/riscv32/fabs.c      | 15 ++++++++++
 src/math/riscv32/fabsf.c     | 15 ++++++++++
 src/math/riscv32/fma.c       | 15 ++++++++++
 src/math/riscv32/fmaf.c      | 15 ++++++++++
 src/math/riscv32/fmax.c      | 15 ++++++++++
 src/math/riscv32/fmaxf.c     | 15 ++++++++++
 src/math/riscv32/fmin.c      | 15 ++++++++++
 src/math/riscv32/fminf.c     | 15 ++++++++++
 src/math/riscv32/sqrt.c      | 15 ++++++++++
 src/math/riscv32/sqrtf.c     | 15 ++++++++++
 14 files changed, 239 insertions(+)
 create mode 100644 src/fenv/riscv32/fenv-sf.c
 create mode 100644 src/fenv/riscv32/fenv.S
 create mode 100644 src/math/riscv32/copysign.c
 create mode 100644 src/math/riscv32/copysignf.c
 create mode 100644 src/math/riscv32/fabs.c
 create mode 100644 src/math/riscv32/fabsf.c
 create mode 100644 src/math/riscv32/fma.c
 create mode 100644 src/math/riscv32/fmaf.c
 create mode 100644 src/math/riscv32/fmax.c
 create mode 100644 src/math/riscv32/fmaxf.c
 create mode 100644 src/math/riscv32/fmin.c
 create mode 100644 src/math/riscv32/fminf.c
 create mode 100644 src/math/riscv32/sqrt.c
 create mode 100644 src/math/riscv32/sqrtf.c

diff --git a/src/fenv/riscv32/fenv-sf.c b/src/fenv/riscv32/fenv-sf.c
new file mode 100644
index 00000000..ecd3cb5c
--- /dev/null
+++ b/src/fenv/riscv32/fenv-sf.c
@@ -0,0 +1,3 @@
+#ifndef __riscv_flen
+#include "../fenv.c"
+#endif
diff --git a/src/fenv/riscv32/fenv.S b/src/fenv/riscv32/fenv.S
new file mode 100644
index 00000000..0ea78bf9
--- /dev/null
+++ b/src/fenv/riscv32/fenv.S
@@ -0,0 +1,56 @@
+#ifdef __riscv_flen
+
+.global feclearexcept
+.type feclearexcept, %function
+feclearexcept:
+	csrc fflags, a0
+	li a0, 0
+	ret
+
+.global feraiseexcept
+.type feraiseexcept, %function
+feraiseexcept:
+	csrs fflags, a0
+	li a0, 0
+	ret
+
+.global fetestexcept
+.type fetestexcept, %function
+fetestexcept:
+	frflags t0
+	and a0, t0, a0
+	ret
+
+.global fegetround
+.type fegetround, %function
+fegetround:
+	frrm a0
+	ret
+
+.global __fesetround
+.type __fesetround, %function
+__fesetround:
+	fsrm t0, a0
+	li a0, 0
+	ret
+
+.global fegetenv
+.type fegetenv, %function
+fegetenv:
+	frcsr t0
+	sw t0, 0(a0)
+	li a0, 0
+	ret
+
+.global fesetenv
+.type fesetenv, %function
+fesetenv:
+	li t2, -1
+	li t1, 0
+	beq a0, t2, 1f
+	lw t1, 0(a0)
+1:	fscsr t1
+	li a0, 0
+	ret
+
+#endif
diff --git a/src/math/riscv32/copysign.c b/src/math/riscv32/copysign.c
new file mode 100644
index 00000000..c7854178
--- /dev/null
+++ b/src/math/riscv32/copysign.c
@@ -0,0 +1,15 @@
+#include <math.h>
+
+#if __riscv_flen >= 64
+
+double copysign(double x, double y)
+{
+	__asm__ ("fsgnj.d %0, %1, %2" : "=f"(x) : "f"(x), "f"(y));
+	return x;
+}
+
+#else
+
+#include "../copysign.c"
+
+#endif
diff --git a/src/math/riscv32/copysignf.c b/src/math/riscv32/copysignf.c
new file mode 100644
index 00000000..a125611a
--- /dev/null
+++ b/src/math/riscv32/copysignf.c
@@ -0,0 +1,15 @@
+#include <math.h>
+
+#if __riscv_flen >= 32
+
+float copysignf(float x, float y)
+{
+	__asm__ ("fsgnj.s %0, %1, %2" : "=f"(x) : "f"(x), "f"(y));
+	return x;
+}
+
+#else
+
+#include "../copysignf.c"
+
+#endif
diff --git a/src/math/riscv32/fabs.c b/src/math/riscv32/fabs.c
new file mode 100644
index 00000000..5290b6f0
--- /dev/null
+++ b/src/math/riscv32/fabs.c
@@ -0,0 +1,15 @@
+#include <math.h>
+
+#if __riscv_flen >= 64
+
+double fabs(double x)
+{
+	__asm__ ("fabs.d %0, %1" : "=f"(x) : "f"(x));
+	return x;
+}
+
+#else
+
+#include "../fabs.c"
+
+#endif
diff --git a/src/math/riscv32/fabsf.c b/src/math/riscv32/fabsf.c
new file mode 100644
index 00000000..f5032e35
--- /dev/null
+++ b/src/math/riscv32/fabsf.c
@@ -0,0 +1,15 @@
+#include <math.h>
+
+#if __riscv_flen >= 32
+
+float fabsf(float x)
+{
+	__asm__ ("fabs.s %0, %1" : "=f"(x) : "f"(x));
+	return x;
+}
+
+#else
+
+#include "../fabsf.c"
+
+#endif
diff --git a/src/math/riscv32/fma.c b/src/math/riscv32/fma.c
new file mode 100644
index 00000000..99b05713
--- /dev/null
+++ b/src/math/riscv32/fma.c
@@ -0,0 +1,15 @@
+#include <math.h>
+
+#if __riscv_flen >= 64
+
+double fma(double x, double y, double z)
+{
+	__asm__ ("fmadd.d %0, %1, %2, %3" : "=f"(x) : "f"(x), "f"(y), "f"(z));
+	return x;
+}
+
+#else
+
+#include "../fma.c"
+
+#endif
diff --git a/src/math/riscv32/fmaf.c b/src/math/riscv32/fmaf.c
new file mode 100644
index 00000000..f9dc47ed
--- /dev/null
+++ b/src/math/riscv32/fmaf.c
@@ -0,0 +1,15 @@
+#include <math.h>
+
+#if __riscv_flen >= 32
+
+float fmaf(float x, float y, float z)
+{
+	__asm__ ("fmadd.s %0, %1, %2, %3" : "=f"(x) : "f"(x), "f"(y), "f"(z));
+	return x;
+}
+
+#else
+
+#include "../fmaf.c"
+
+#endif
diff --git a/src/math/riscv32/fmax.c b/src/math/riscv32/fmax.c
new file mode 100644
index 00000000..023709cd
--- /dev/null
+++ b/src/math/riscv32/fmax.c
@@ -0,0 +1,15 @@
+#include <math.h>
+
+#if __riscv_flen >= 64
+
+double fmax(double x, double y)
+{
+	__asm__ ("fmax.d %0, %1, %2" : "=f"(x) : "f"(x), "f"(y));
+	return x;
+}
+
+#else
+
+#include "../fmax.c"
+
+#endif
diff --git a/src/math/riscv32/fmaxf.c b/src/math/riscv32/fmaxf.c
new file mode 100644
index 00000000..863d2bd1
--- /dev/null
+++ b/src/math/riscv32/fmaxf.c
@@ -0,0 +1,15 @@
+#include <math.h>
+
+#if __riscv_flen >= 32
+
+float fmaxf(float x, float y)
+{
+	__asm__ ("fmax.s %0, %1, %2" : "=f"(x) : "f"(x), "f"(y));
+	return x;
+}
+
+#else
+
+#include "../fmaxf.c"
+
+#endif
diff --git a/src/math/riscv32/fmin.c b/src/math/riscv32/fmin.c
new file mode 100644
index 00000000..a4e3b067
--- /dev/null
+++ b/src/math/riscv32/fmin.c
@@ -0,0 +1,15 @@
+#include <math.h>
+
+#if __riscv_flen >= 64
+
+double fmin(double x, double y)
+{
+	__asm__ ("fmin.d %0, %1, %2" : "=f"(x) : "f"(x), "f"(y));
+	return x;
+}
+
+#else
+
+#include "../fmin.c"
+
+#endif
diff --git a/src/math/riscv32/fminf.c b/src/math/riscv32/fminf.c
new file mode 100644
index 00000000..32156e80
--- /dev/null
+++ b/src/math/riscv32/fminf.c
@@ -0,0 +1,15 @@
+#include <math.h>
+
+#if __riscv_flen >= 32
+
+float fminf(float x, float y)
+{
+	__asm__ ("fmin.s %0, %1, %2" : "=f"(x) : "f"(x), "f"(y));
+	return x;
+}
+
+#else
+
+#include "../fminf.c"
+
+#endif
diff --git a/src/math/riscv32/sqrt.c b/src/math/riscv32/sqrt.c
new file mode 100644
index 00000000..867a504c
--- /dev/null
+++ b/src/math/riscv32/sqrt.c
@@ -0,0 +1,15 @@
+#include <math.h>
+
+#if __riscv_flen >= 64
+
+double sqrt(double x)
+{
+	__asm__ ("fsqrt.d %0, %1" : "=f"(x) : "f"(x));
+	return x;
+}
+
+#else
+
+#include "../sqrt.c"
+
+#endif
diff --git a/src/math/riscv32/sqrtf.c b/src/math/riscv32/sqrtf.c
new file mode 100644
index 00000000..610c2cf8
--- /dev/null
+++ b/src/math/riscv32/sqrtf.c
@@ -0,0 +1,15 @@
+#include <math.h>
+
+#if __riscv_flen >= 32
+
+float sqrtf(float x)
+{
+	__asm__ ("fsqrt.s %0, %1" : "=f"(x) : "f"(x));
+	return x;
+}
+
+#else
+
+#include "../sqrtf.c"
+
+#endif
-- 
2.25.4


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

* [musl] [PATCH 12/14] riscv32: Add dlsym
  2020-09-03 11:22 [musl] [PATCH 00/14] riscv32 support Stefan O'Rear
                   ` (10 preceding siblings ...)
  2020-09-03 11:23 ` [musl] [PATCH 11/14] riscv32: Add fenv and math Stefan O'Rear
@ 2020-09-03 11:23 ` Stefan O'Rear
  2020-09-03 11:23 ` [musl] [PATCH 13/14] riscv32: Add jmp_buf and sigreturn Stefan O'Rear
  2020-09-03 11:23 ` [musl] [PATCH 14/14] riscv32: Add thread support Stefan O'Rear
  13 siblings, 0 replies; 31+ messages in thread
From: Stefan O'Rear @ 2020-09-03 11:23 UTC (permalink / raw)
  To: musl; +Cc: Stefan O'Rear

Identical to riscv64.
---
 src/ldso/riscv32/dlsym.s | 6 ++++++
 1 file changed, 6 insertions(+)
 create mode 100644 src/ldso/riscv32/dlsym.s

diff --git a/src/ldso/riscv32/dlsym.s b/src/ldso/riscv32/dlsym.s
new file mode 100644
index 00000000..2bafd72d
--- /dev/null
+++ b/src/ldso/riscv32/dlsym.s
@@ -0,0 +1,6 @@
+.global dlsym
+.hidden __dlsym
+.type dlsym, %function
+dlsym:
+	mv a2, ra
+	tail __dlsym
-- 
2.25.4


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

* [musl] [PATCH 13/14] riscv32: Add jmp_buf and sigreturn
  2020-09-03 11:22 [musl] [PATCH 00/14] riscv32 support Stefan O'Rear
                   ` (11 preceding siblings ...)
  2020-09-03 11:23 ` [musl] [PATCH 12/14] riscv32: Add dlsym Stefan O'Rear
@ 2020-09-03 11:23 ` Stefan O'Rear
  2020-09-03 11:23 ` [musl] [PATCH 14/14] riscv32: Add thread support Stefan O'Rear
  13 siblings, 0 replies; 31+ messages in thread
From: Stefan O'Rear @ 2020-09-03 11:23 UTC (permalink / raw)
  To: musl; +Cc: Stefan O'Rear

Largely copied from riscv64 but required recalculation of offsets.
---
 src/setjmp/riscv32/longjmp.S   | 42 ++++++++++++++++++++++++++++++++++
 src/setjmp/riscv32/setjmp.S    | 41 +++++++++++++++++++++++++++++++++
 src/signal/riscv32/restore.s   |  8 +++++++
 src/signal/riscv32/sigsetjmp.s | 23 +++++++++++++++++++
 4 files changed, 114 insertions(+)
 create mode 100644 src/setjmp/riscv32/longjmp.S
 create mode 100644 src/setjmp/riscv32/setjmp.S
 create mode 100644 src/signal/riscv32/restore.s
 create mode 100644 src/signal/riscv32/sigsetjmp.s

diff --git a/src/setjmp/riscv32/longjmp.S b/src/setjmp/riscv32/longjmp.S
new file mode 100644
index 00000000..f9cb3318
--- /dev/null
+++ b/src/setjmp/riscv32/longjmp.S
@@ -0,0 +1,42 @@
+.global __longjmp
+.global _longjmp
+.global longjmp
+.type __longjmp, %function
+.type _longjmp,  %function
+.type longjmp,   %function
+__longjmp:
+_longjmp:
+longjmp:
+	lw s0,    0(a0)
+	lw s1,    4(a0)
+	lw s2,    8(a0)
+	lw s3,    12(a0)
+	lw s4,    16(a0)
+	lw s5,    20(a0)
+	lw s6,    24(a0)
+	lw s7,    28(a0)
+	lw s8,    32(a0)
+	lw s9,    36(a0)
+	lw s10,   40(a0)
+	lw s11,   44(a0)
+	lw sp,    48(a0)
+	lw ra,    52(a0)
+
+#ifndef __riscv_float_abi_soft
+	fld fs0,  56(a0)
+	fld fs1,  64(a0)
+	fld fs2,  72(a0)
+	fld fs3,  80(a0)
+	fld fs4,  88(a0)
+	fld fs5,  96(a0)
+	fld fs6,  104(a0)
+	fld fs7,  112(a0)
+	fld fs8,  120(a0)
+	fld fs9,  128(a0)
+	fld fs10, 136(a0)
+	fld fs11, 144(a0)
+#endif
+
+	seqz a0, a1
+	add a0, a0, a1
+	ret
diff --git a/src/setjmp/riscv32/setjmp.S b/src/setjmp/riscv32/setjmp.S
new file mode 100644
index 00000000..8a75cf55
--- /dev/null
+++ b/src/setjmp/riscv32/setjmp.S
@@ -0,0 +1,41 @@
+.global __setjmp
+.global _setjmp
+.global setjmp
+.type __setjmp, %function
+.type _setjmp,  %function
+.type setjmp,   %function
+__setjmp:
+_setjmp:
+setjmp:
+	sw s0,    0(a0)
+	sw s1,    4(a0)
+	sw s2,    8(a0)
+	sw s3,    12(a0)
+	sw s4,    16(a0)
+	sw s5,    20(a0)
+	sw s6,    24(a0)
+	sw s7,    28(a0)
+	sw s8,    32(a0)
+	sw s9,    36(a0)
+	sw s10,   40(a0)
+	sw s11,   44(a0)
+	sw sp,    48(a0)
+	sw ra,    52(a0)
+
+#ifndef __riscv_float_abi_soft
+	fsd fs0,  56(a0)
+	fsd fs1,  64(a0)
+	fsd fs2,  72(a0)
+	fsd fs3,  80(a0)
+	fsd fs4,  88(a0)
+	fsd fs5,  96(a0)
+	fsd fs6,  104(a0)
+	fsd fs7,  112(a0)
+	fsd fs8,  120(a0)
+	fsd fs9,  128(a0)
+	fsd fs10, 136(a0)
+	fsd fs11, 144(a0)
+#endif
+
+	li a0, 0
+	ret
diff --git a/src/signal/riscv32/restore.s b/src/signal/riscv32/restore.s
new file mode 100644
index 00000000..40012c75
--- /dev/null
+++ b/src/signal/riscv32/restore.s
@@ -0,0 +1,8 @@
+.global __restore
+.type __restore, %function
+__restore:
+.global __restore_rt
+.type __restore_rt, %function
+__restore_rt:
+	li a7, 139 # SYS_rt_sigreturn
+	ecall
diff --git a/src/signal/riscv32/sigsetjmp.s b/src/signal/riscv32/sigsetjmp.s
new file mode 100644
index 00000000..c1caeab1
--- /dev/null
+++ b/src/signal/riscv32/sigsetjmp.s
@@ -0,0 +1,23 @@
+.global sigsetjmp
+.global __sigsetjmp
+.type sigsetjmp, %function
+.type __sigsetjmp, %function
+sigsetjmp:
+__sigsetjmp:
+	bnez a1, 1f
+	tail setjmp
+1:
+
+	sw ra, 152(a0)
+	sw s0, 164(a0)
+	mv s0, a0
+
+	call setjmp
+
+	mv a1, a0
+	mv a0, s0
+	lw s0, 164(a0)
+	lw ra, 152(a0)
+
+.hidden __sigsetjmp_tail
+	tail __sigsetjmp_tail
-- 
2.25.4


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

* [musl] [PATCH 14/14] riscv32: Add thread support
  2020-09-03 11:22 [musl] [PATCH 00/14] riscv32 support Stefan O'Rear
                   ` (12 preceding siblings ...)
  2020-09-03 11:23 ` [musl] [PATCH 13/14] riscv32: Add jmp_buf and sigreturn Stefan O'Rear
@ 2020-09-03 11:23 ` Stefan O'Rear
  13 siblings, 0 replies; 31+ messages in thread
From: Stefan O'Rear @ 2020-09-03 11:23 UTC (permalink / raw)
  To: musl; +Cc: Stefan O'Rear

Identical to riscv64 except for stack offsets in clone.
---
 src/thread/riscv32/__set_thread_area.s |  6 +++++
 src/thread/riscv32/__unmapself.s       |  7 ++++++
 src/thread/riscv32/clone.s             | 34 ++++++++++++++++++++++++++
 src/thread/riscv32/syscall_cp.s        | 29 ++++++++++++++++++++++
 4 files changed, 76 insertions(+)
 create mode 100644 src/thread/riscv32/__set_thread_area.s
 create mode 100644 src/thread/riscv32/__unmapself.s
 create mode 100644 src/thread/riscv32/clone.s
 create mode 100644 src/thread/riscv32/syscall_cp.s

diff --git a/src/thread/riscv32/__set_thread_area.s b/src/thread/riscv32/__set_thread_area.s
new file mode 100644
index 00000000..828154d2
--- /dev/null
+++ b/src/thread/riscv32/__set_thread_area.s
@@ -0,0 +1,6 @@
+.global __set_thread_area
+.type   __set_thread_area, %function
+__set_thread_area:
+	mv tp, a0
+	li a0, 0
+	ret
diff --git a/src/thread/riscv32/__unmapself.s b/src/thread/riscv32/__unmapself.s
new file mode 100644
index 00000000..2849119c
--- /dev/null
+++ b/src/thread/riscv32/__unmapself.s
@@ -0,0 +1,7 @@
+.global __unmapself
+.type __unmapself, %function
+__unmapself:
+	li a7, 215 # SYS_munmap
+	ecall
+	li a7, 93  # SYS_exit
+	ecall
diff --git a/src/thread/riscv32/clone.s b/src/thread/riscv32/clone.s
new file mode 100644
index 00000000..3102239d
--- /dev/null
+++ b/src/thread/riscv32/clone.s
@@ -0,0 +1,34 @@
+# __clone(func, stack, flags, arg, ptid, tls, ctid)
+#           a0,    a1,    a2,  a3,   a4,  a5,   a6
+
+# syscall(SYS_clone, flags, stack, ptid, tls, ctid)
+#                a7     a0,    a1,   a2,  a3,   a4
+
+.global __clone
+.type  __clone, %function
+__clone:
+	# Save func and arg to stack
+	addi a1, a1, -16
+	sw a0, 0(a1)
+	sw a3, 4(a1)
+
+	# Call SYS_clone
+	mv a0, a2
+	mv a2, a4
+	mv a3, a5
+	mv a4, a6
+	li a7, 220 # SYS_clone
+	ecall
+
+	beqz a0, 1f
+	# Parent
+	ret
+
+	# Child
+1:      lw a1, 0(sp)
+	lw a0, 4(sp)
+	jalr a1
+
+	# Exit
+	li a7, 93 # SYS_exit
+	ecall
diff --git a/src/thread/riscv32/syscall_cp.s b/src/thread/riscv32/syscall_cp.s
new file mode 100644
index 00000000..079d1ba0
--- /dev/null
+++ b/src/thread/riscv32/syscall_cp.s
@@ -0,0 +1,29 @@
+.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
+__syscall_cp_asm:
+__cp_begin:
+	lw t0, 0(a0)
+	bnez t0, __cp_cancel
+
+	mv t0, a1
+	mv a0, a2
+	mv a1, a3
+	mv a2, a4
+	mv a3, a5
+	mv a4, a6
+	mv a5, a7
+	lw a6, 0(sp)
+	mv a7, t0
+	ecall
+__cp_end:
+	ret
+__cp_cancel:
+	tail __cancel
-- 
2.25.4


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

* Re: [musl] [PATCH 07/14] Emulate wait4 using waitid
  2020-09-03 11:23 ` [musl] [PATCH 07/14] Emulate wait4 using waitid Stefan O'Rear
@ 2020-09-03 14:56   ` Stefan O'Rear
  2020-09-03 15:36     ` Arnd Bergmann
  2020-09-03 15:49   ` Rich Felker
  1 sibling, 1 reply; 31+ messages in thread
From: Stefan O'Rear @ 2020-09-03 14:56 UTC (permalink / raw)
  To: musl

On Thu, Sep 3, 2020, at 7:23 AM, Stefan O'Rear wrote:
> +		case CLD_STOPPED:
> +		case CLD_TRAPPED:
> +			sw = ((info.si_status&0xff) << 8) + 0x7f;
> +			break;

This is trying to be defensive but it is the cause of the strace issue
in the cover letter since the ptrace interface generates si_status
greater than 8 bits which must be visible in WSTOPSIG; the v2 will not
mask here.

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

* Re: [musl] [PATCH 07/14] Emulate wait4 using waitid
  2020-09-03 14:56   ` Stefan O'Rear
@ 2020-09-03 15:36     ` Arnd Bergmann
  2020-09-03 15:40       ` Stefan O'Rear
  0 siblings, 1 reply; 31+ messages in thread
From: Arnd Bergmann @ 2020-09-03 15:36 UTC (permalink / raw)
  To: musl

On Thu, Sep 3, 2020 at 4:56 PM Stefan O'Rear <sorear@fastmail.com> wrote:
>
> On Thu, Sep 3, 2020, at 7:23 AM, Stefan O'Rear wrote:
> > +             case CLD_STOPPED:
> > +             case CLD_TRAPPED:
> > +                     sw = ((info.si_status&0xff) << 8) + 0x7f;
> > +                     break;
>
> This is trying to be defensive but it is the cause of the strace issue
> in the cover letter since the ptrace interface generates si_status
> greater than 8 bits which must be visible in WSTOPSIG; the v2 will not
> mask here.

Ah, I was trying to find out what exactly the masking was for since
I did not have that in my original version of the same function for Arm:


+       if (status) {
+               *status = 0;
+               switch (info.si_code) {
+               case CLD_EXITED:
+                       *status = info.si_status << 8;
+                       break;
+               case CLD_DUMPED:
+                       *status = 0x80;
+               case CLD_KILLED:
+                       *status |= info.si_status;
+                       break;
+               case CLD_TRAPPED:
+               case CLD_STOPPED:
+                       *status = info.si_status << 8 | 0x7f;
+                       break;
+               case CLD_CONTINUED:
+                       *status = 0xffff;
+                       break;
+               }
+       }

Aside from the mask, this seems to be functionally the same.

      Arnd

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

* Re: [musl] [PATCH 05/14] Add src/internal/statx.h
  2020-09-03 11:23 ` [musl] [PATCH 05/14] Add src/internal/statx.h Stefan O'Rear
@ 2020-09-03 15:39   ` Arnd Bergmann
  2020-09-03 15:51     ` Rich Felker
  0 siblings, 1 reply; 31+ messages in thread
From: Arnd Bergmann @ 2020-09-03 15:39 UTC (permalink / raw)
  To: musl; +Cc: Stefan O'Rear

On Thu, Sep 3, 2020 at 1:24 PM Stefan O'Rear <sorear@fastmail.com> wrote:
>
> We need to make internal syscalls to SYS_statx when SYS_fstatat is not
> available without changing the musl API.
> ---
>  src/internal/statx.h | 28 ++++++++++++++++++++++++++++
>  src/stat/fstatat.c   | 28 ++--------------------------
>  2 files changed, 30 insertions(+), 26 deletions(-)
>  create mode 100644 src/internal/statx.h
>
> diff --git a/src/internal/statx.h b/src/internal/statx.h
> new file mode 100644
> index 00000000..46b16f62
> --- /dev/null
> +++ b/src/internal/statx.h
> @@ -0,0 +1,28 @@
> +struct statx {
> +       uint32_t stx_mask;
> +       uint32_t stx_blksize;
> +       uint64_t stx_attributes;
> +       uint32_t stx_nlink;
> +       uint32_t stx_uid;
> +       uint32_t stx_gid;
> +       uint16_t stx_mode;
> +       uint16_t pad1;
> +       uint64_t stx_ino;
> +       uint64_t stx_size;
> +       uint64_t stx_blocks;
> +       uint64_t stx_attributes_mask;
> +       struct {
> +               int64_t tv_sec;
> +               uint32_t tv_nsec;
> +               int32_t pad;
> +       } stx_atime, stx_btime, stx_ctime, stx_mtime;
> +       uint32_t stx_rdev_major;
> +       uint32_t stx_rdev_minor;
> +       uint32_t stx_dev_major;
> +       uint32_t stx_dev_minor;
> +       uint64_t spare[14];
> +};

Unrelated to your patch that just moves this, I notice that
the kernel version has gained an stx_mnt_id field.

     Arnd

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

* Re: [musl] [PATCH 07/14] Emulate wait4 using waitid
  2020-09-03 15:36     ` Arnd Bergmann
@ 2020-09-03 15:40       ` Stefan O'Rear
  2020-09-03 18:08         ` Arnd Bergmann
  0 siblings, 1 reply; 31+ messages in thread
From: Stefan O'Rear @ 2020-09-03 15:40 UTC (permalink / raw)
  To: musl

On Thu, Sep 3, 2020, at 11:36 AM, Arnd Bergmann wrote:
> On Thu, Sep 3, 2020 at 4:56 PM Stefan O'Rear <sorear@fastmail.com> wrote:
> >
> > On Thu, Sep 3, 2020, at 7:23 AM, Stefan O'Rear wrote:
> > > +             case CLD_STOPPED:
> > > +             case CLD_TRAPPED:
> > > +                     sw = ((info.si_status&0xff) << 8) + 0x7f;
> > > +                     break;
> >
> > This is trying to be defensive but it is the cause of the strace issue
> > in the cover letter since the ptrace interface generates si_status
> > greater than 8 bits which must be visible in WSTOPSIG; the v2 will not
> > mask here.
> 
> Ah, I was trying to find out what exactly the masking was for since
> I did not have that in my original version of the same function for Arm:

Where is this coming from?  I didn't want to blindly copy code from glibc
and I couldn't find any documentation of how the mapping is supposed
to work other than the POSIX descriptions of the wait and waitid functions
(which is why I missed the non-POSIX ptrace cases).

If there's an authoritative description of the mapping I would like to match
it exactly.
 
-s

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

* Re: [musl] [PATCH 10/14] riscv32: add arch headers
  2020-09-03 11:23 ` [musl] [PATCH 10/14] riscv32: add arch headers Stefan O'Rear
@ 2020-09-03 15:49   ` Arnd Bergmann
  0 siblings, 0 replies; 31+ messages in thread
From: Arnd Bergmann @ 2020-09-03 15:49 UTC (permalink / raw)
  To: musl; +Cc: Stefan O'Rear

On Thu, Sep 3, 2020 at 1:25 PM Stefan O'Rear <sorear@fastmail.com> wrote:
> diff --git a/arch/riscv32/bits/fcntl.h b/arch/riscv32/bits/fcntl.h
> new file mode 100644
> index 00000000..ecb4d18f
> --- /dev/null
> +++ b/arch/riscv32/bits/fcntl.h
> @@ -0,0 +1,38 @@
> +#define O_CREAT        0100
> +#define O_EXCL         0200
> +#define O_NOCTTY       0400

I see a arch/generic/bits/fcntl.h that seems to have identical contents.

Is this one actually needed?

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

* Re: [musl] [PATCH 07/14] Emulate wait4 using waitid
  2020-09-03 11:23 ` [musl] [PATCH 07/14] Emulate wait4 using waitid Stefan O'Rear
  2020-09-03 14:56   ` Stefan O'Rear
@ 2020-09-03 15:49   ` Rich Felker
  2020-09-03 16:25     ` Stefan O'Rear
  1 sibling, 1 reply; 31+ messages in thread
From: Rich Felker @ 2020-09-03 15:49 UTC (permalink / raw)
  To: musl

On Thu, Sep 03, 2020 at 07:23:02AM -0400, Stefan O'Rear wrote:
> riscv32 and future architectures lack wait4.
> ---
>  src/internal/wait4_waitid.h |  1 +
>  src/linux/__wait4_waitid.c  | 52 +++++++++++++++++++++++++++++++++++++
>  src/linux/wait4.c           |  5 ++++
>  src/process/waitpid.c       |  6 +++++
>  src/stdio/pclose.c          |  6 +++++
>  src/unistd/faccessat.c      |  6 ++++-
>  6 files changed, 75 insertions(+), 1 deletion(-)
>  create mode 100644 src/internal/wait4_waitid.h
>  create mode 100644 src/linux/__wait4_waitid.c

I really don't like introducing a new src/internal file for this. If
the code needs to be shared it should probably just be in wait4.c,
renamed to __wait4, declared in src/include/sys/wait.h according to
the usual pattern for exposing namespace-safe versions of
namespace-violating functions.

Ideally I'd like to just not need it, but I'm not sure that's
possible:

- faccessat throws away the status and doesn't have any need for the
  status or idtype emulation code. It could easily be just different
  syscalls in #ifdef/#else paths.

- pclose does need status but not the idtype part. but it's only
  listening for process termination not all the other weird stuff. I'm
  not sure if it would make sense to construct status inline here. It
  might if we had a macro like the glibc "inverse-W" macro (I forget
  its name) to construct a wait status from parts; if so this could
  later be considered for a public API (previously requested).

- waitpid and wait4 at least need the idtype and status construction.

Unfortunately, wait4 also needs the rusage conversion, which waitpid
doesn't want. This kinda defeats my idea of just exposing __wait4 from
wait4.c.

A side observation to keep in mind is that passing the argument cp
doesn't really help optimize anything; it only worked well in
c2feda4e2e because the function there is inline. Of the 4 callers you
have, faccessat and pclose have hard requirements not to be a
cancellation point and waitpid has a hard requirement to be one. But
if the function weren't used for the former, it could just always be
cancellable -- wait4 probably should have been cancellable all along,
and almost surely is on other implementations, so to use it safely
you'd have to not use, block, or handle cancellation.

So I'm leaning towards sticking with something like what you've done,
but with declaration moved to src/include/sys/wait.h, or possibly
src/internal/syscall.h (since it's essentially emulation of a
syscall). Inline in src/internal/syscall.h might also be an option;
one appealing aspect of that is that it would get rid of the #ifdefs
in source files and allow calling __sys_wait4() unconditionally with
no codegen regression on existing archs. This is analogous to
__sys_open[23].

Rich

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

* Re: [musl] [PATCH 05/14] Add src/internal/statx.h
  2020-09-03 15:39   ` Arnd Bergmann
@ 2020-09-03 15:51     ` Rich Felker
  2020-09-03 18:08       ` Arnd Bergmann
  0 siblings, 1 reply; 31+ messages in thread
From: Rich Felker @ 2020-09-03 15:51 UTC (permalink / raw)
  To: musl

On Thu, Sep 03, 2020 at 05:39:51PM +0200, Arnd Bergmann wrote:
> On Thu, Sep 3, 2020 at 1:24 PM Stefan O'Rear <sorear@fastmail.com> wrote:
> >
> > We need to make internal syscalls to SYS_statx when SYS_fstatat is not
> > available without changing the musl API.
> > ---
> >  src/internal/statx.h | 28 ++++++++++++++++++++++++++++
> >  src/stat/fstatat.c   | 28 ++--------------------------
> >  2 files changed, 30 insertions(+), 26 deletions(-)
> >  create mode 100644 src/internal/statx.h
> >
> > diff --git a/src/internal/statx.h b/src/internal/statx.h
> > new file mode 100644
> > index 00000000..46b16f62
> > --- /dev/null
> > +++ b/src/internal/statx.h
> > @@ -0,0 +1,28 @@
> > +struct statx {
> > +       uint32_t stx_mask;
> > +       uint32_t stx_blksize;
> > +       uint64_t stx_attributes;
> > +       uint32_t stx_nlink;
> > +       uint32_t stx_uid;
> > +       uint32_t stx_gid;
> > +       uint16_t stx_mode;
> > +       uint16_t pad1;
> > +       uint64_t stx_ino;
> > +       uint64_t stx_size;
> > +       uint64_t stx_blocks;
> > +       uint64_t stx_attributes_mask;
> > +       struct {
> > +               int64_t tv_sec;
> > +               uint32_t tv_nsec;
> > +               int32_t pad;
> > +       } stx_atime, stx_btime, stx_ctime, stx_mtime;
> > +       uint32_t stx_rdev_major;
> > +       uint32_t stx_rdev_minor;
> > +       uint32_t stx_dev_major;
> > +       uint32_t stx_dev_minor;
> > +       uint64_t spare[14];
> > +};
> 
> Unrelated to your patch that just moves this, I notice that
> the kernel version has gained an stx_mnt_id field.

This could potentially be added, but should be a separate change, and
really only makes sense if/when we put this in a public header since
nothing internal is using it.

Rich

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

* Re: [musl] [PATCH 02/14] time64: Don't make aliases to nonexistent syscalls
  2020-09-03 11:22 ` [musl] [PATCH 02/14] time64: Don't make aliases to nonexistent syscalls Stefan O'Rear
@ 2020-09-03 15:56   ` Rich Felker
  2020-09-03 19:36     ` Stefan O'Rear
  0 siblings, 1 reply; 31+ messages in thread
From: Rich Felker @ 2020-09-03 15:56 UTC (permalink / raw)
  To: musl

On Thu, Sep 03, 2020 at 07:22:57AM -0400, Stefan O'Rear wrote:
> riscv32 and future architectures lack the _time32 variants entirely, so
> don't try to use their numbers.
> ---
>  src/internal/syscall.h | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/src/internal/syscall.h b/src/internal/syscall.h
> index d5f294d4..66fc4e5c 100644
> --- a/src/internal/syscall.h
> +++ b/src/internal/syscall.h
> @@ -201,6 +201,7 @@ static inline long __alt_socketcall(int sys, int sock, int cp, long a, long b, l
>  #define SYS_sendfile SYS_sendfile64
>  #endif
>  
> +#ifdef SYS_timer_settime32
>  #ifndef SYS_timer_settime
>  #define SYS_timer_settime SYS_timer_settime32
>  #endif
> @@ -240,6 +241,7 @@ static inline long __alt_socketcall(int sys, int sock, int cp, long a, long b, l
>  #ifndef SYS_settimeofday
>  #define SYS_settimeofday SYS_settimeofday_time32
>  #endif
> +#endif

The existing expectation internally in musl is that archs that lack
legacy time32 syscalls have both the unadorned and _time64 macros
defined to the same value. The public headers don't have to be like
that but the internal ones do. See arch/x32/syscall_arch.h which does
it but in the opposite direction. This logic is all tested for x32 and
a big part of the point of that was preparing for rv32 and future
32-bit archs.

I'm actually missing how this patch worked as-written, since for
example timer_settime.c unconditionally assumes SYS_timer_settime is
defined, and if it's defined to anything other than the same value as
the time64 version, it will use the value as a fallback.

Rich

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

* Re: [musl] [PATCH 06/14] Only call fstatat if defined
  2020-09-03 11:23 ` [musl] [PATCH 06/14] Only call fstatat if defined Stefan O'Rear
@ 2020-09-03 16:05   ` Rich Felker
  2020-09-04  1:47     ` Stefan O'Rear
  0 siblings, 1 reply; 31+ messages in thread
From: Rich Felker @ 2020-09-03 16:05 UTC (permalink / raw)
  To: musl

On Thu, Sep 03, 2020 at 07:23:01AM -0400, Stefan O'Rear wrote:
> riscv32 and future architectures lack it.
> ---
>  src/stat/fchmodat.c   | 22 +++++++++++++++++++++-
>  src/stat/fstatat.c    |  6 ++++++
>  src/stdio/tempnam.c   |  7 +++++++
>  src/stdio/tmpnam.c    |  7 +++++++
>  src/time/__map_file.c | 13 ++++++++++++-
>  5 files changed, 53 insertions(+), 2 deletions(-)
> 
> diff --git a/src/stat/fchmodat.c b/src/stat/fchmodat.c
> index 4ee00b0a..bcd44cc8 100644
> --- a/src/stat/fchmodat.c
> +++ b/src/stat/fchmodat.c
> @@ -1,8 +1,10 @@
>  #include <sys/stat.h>
>  #include <fcntl.h>
>  #include <errno.h>
> +#include <stdint.h>
>  #include "syscall.h"
>  #include "kstat.h"
> +#include "statx.h"
>  
>  int fchmodat(int fd, const char *path, mode_t mode, int flag)
>  {
> @@ -11,14 +13,24 @@ int fchmodat(int fd, const char *path, mode_t mode, int flag)
>  	if (flag != AT_SYMLINK_NOFOLLOW)
>  		return __syscall_ret(-EINVAL);
>  
> -	struct kstat st;
>  	int ret, fd2;
>  	char proc[15+3*sizeof(int)];
>  
> +#ifdef SYS_fstatat
> +	struct kstat st;
>  	if ((ret = __syscall(SYS_fstatat, fd, path, &st, flag)))
>  		return __syscall_ret(ret);
> +
>  	if (S_ISLNK(st.st_mode))
>  		return __syscall_ret(-EOPNOTSUPP);
> +#else
> +	struct statx st;
> +	if ((ret = __syscall(SYS_statx, fd, path, flag, STATX_TYPE, &st)))
> +		return __syscall_ret(ret);
> +
> +	if (S_ISLNK(st.stx_mode))
> +		return __syscall_ret(-EOPNOTSUPP);
> +#endif

Can you do this as mode_t mode = st.st[x]_mode; inside the conditional
block and unconditional if (S_ISLNK(mode)) ... outside? This ensures
that the actual logic is not duplicated so it can't become
inconsistent.

> @@ -27,11 +39,19 @@ int fchmodat(int fd, const char *path, mode_t mode, int flag)
>  	}
>  
>  	__procfdname(proc, fd2);
> +#ifdef SYS_fstatat
>  	ret = __syscall(SYS_fstatat, AT_FDCWD, proc, &st, 0);
>  	if (!ret) {
>  		if (S_ISLNK(st.st_mode)) ret = -EOPNOTSUPP;
>  		else ret = __syscall(SYS_fchmodat, AT_FDCWD, proc, mode);
>  	}
> +#else
> +	ret = __syscall(SYS_statx, AT_FDCWD, proc, 0, STATX_TYPE, &st);
> +	if (!ret) {
> +		if (S_ISLNK(st.stx_mode)) ret = -EOPNOTSUPP;
> +		else ret = __syscall(SYS_fchmodat, AT_FDCWD, proc, mode);
> +	}
> +#endif

Same here where even more logic is duplicated.

> diff --git a/src/stat/fstatat.c b/src/stat/fstatat.c
> index 230a83fc..0486f21a 100644
> --- a/src/stat/fstatat.c
> +++ b/src/stat/fstatat.c
> @@ -45,6 +45,7 @@ static int fstatat_statx(int fd, const char *restrict path, struct stat *restric
>  	return 0;
>  }
>  
> +#ifdef SYS_fstatat
>  static int fstatat_kstat(int fd, const char *restrict path, struct stat *restrict st, int flag)
>  {
>  	int ret;
> @@ -106,15 +107,20 @@ static int fstatat_kstat(int fd, const char *restrict path, struct stat *restric
>  
>  	return 0;
>  }
> +#endif
>  
>  int fstatat(int fd, const char *restrict path, struct stat *restrict st, int flag)
>  {
>  	int ret;
> +#ifdef SYS_fstatat
>  	if (sizeof((struct kstat){0}.st_atime_sec) < sizeof(time_t)) {
>  		ret = fstatat_statx(fd, path, st, flag);
>  		if (ret!=-ENOSYS) return __syscall_ret(ret);
>  	}
>  	ret = fstatat_kstat(fd, path, st, flag);
> +#else
> +	ret = fstatat_statx(fd, path, st, flag);
> +#endif
>  	return __syscall_ret(ret);
>  }

I'd like to have this streamlined more without duplicating the call,
but it's not really any big deal, just a little bit ugly, and I don't
see a better way to do it while preserving use of SYS_fstatat
everywhere it's sufficient.

> diff --git a/src/stdio/tempnam.c b/src/stdio/tempnam.c
> index 565df6b6..023ff422 100644
> --- a/src/stdio/tempnam.c
> +++ b/src/stdio/tempnam.c
> @@ -5,8 +5,10 @@
>  #include <limits.h>
>  #include <string.h>
>  #include <stdlib.h>
> +#include <stdint.h>
>  #include "syscall.h"
>  #include "kstat.h"
> +#include "statx.h"
>  
>  #define MAXTRIES 100
>  
> @@ -40,8 +42,13 @@ char *tempnam(const char *dir, const char *pfx)
>  #ifdef SYS_lstat
>  		r = __syscall(SYS_lstat, s, &(struct kstat){0});
>  #else
> +#ifdef SYS_fstatat
>  		r = __syscall(SYS_fstatat, AT_FDCWD, s,
>  			&(struct kstat){0}, AT_SYMLINK_NOFOLLOW);
> +#else
> +		r = __syscall(SYS_statx, AT_FDCWD, s, AT_SYMLINK_NOFOLLOW, 0,
> +			&(struct statx){0});
> +#endif
>  #endif

Can be #elif. Also, is zero request mask ok here?

> diff --git a/src/stdio/tmpnam.c b/src/stdio/tmpnam.c
> index d667a836..c63dabcb 100644
> --- a/src/stdio/tmpnam.c
> +++ b/src/stdio/tmpnam.c
> @@ -4,8 +4,10 @@
>  #include <sys/stat.h>
>  #include <string.h>
>  #include <stdlib.h>
> +#include <stdint.h>
>  #include "syscall.h"
>  #include "kstat.h"
> +#include "statx.h"
>  
>  #define MAXTRIES 100
>  
> @@ -20,8 +22,13 @@ char *tmpnam(char *buf)
>  #ifdef SYS_lstat
>  		r = __syscall(SYS_lstat, s, &(struct kstat){0});
>  #else
> +#ifdef SYS_fstatat
>  		r = __syscall(SYS_fstatat, AT_FDCWD, s,
>  			&(struct kstat){0}, AT_SYMLINK_NOFOLLOW);
> +#else
> +		r = __syscall(SYS_statx, AT_FDCWD, s, AT_SYMLINK_NOFOLLOW, 0,
> +			&(struct statx){0});
> +#endif
>  #endif

Same.

>  		if (r == -ENOENT) return strcpy(buf ? buf : internal, s);
>  	}
> diff --git a/src/time/__map_file.c b/src/time/__map_file.c
> index d3cefa82..f80752bc 100644
> --- a/src/time/__map_file.c
> +++ b/src/time/__map_file.c
> @@ -1,19 +1,30 @@
> +#define _BSD_SOURCE
>  #include <sys/mman.h>
>  #include <fcntl.h>
>  #include <sys/stat.h>
> +#include <stdint.h>
>  #include "syscall.h"
>  #include "kstat.h"
> +#include "statx.h"
>  
>  const char unsigned *__map_file(const char *pathname, size_t *size)
>  {
> -	struct kstat st;
>  	const unsigned char *map = MAP_FAILED;
>  	int fd = sys_open(pathname, O_RDONLY|O_CLOEXEC|O_NONBLOCK);
>  	if (fd < 0) return 0;
> +#ifdef SYS_fstat
> +	struct kstat st;
>  	if (!syscall(SYS_fstat, fd, &st)) {
>  		map = __mmap(0, st.st_size, PROT_READ, MAP_SHARED, fd, 0);
>  		*size = st.st_size;
>  	}
> +#else
> +	struct statx st;
> +	if (!syscall(SYS_statx, fd, "", AT_EMPTY_PATH, STATX_SIZE, &st)) {
> +		map = __mmap(0, st.stx_size, PROT_READ, MAP_SHARED, fd, 0);
> +		*size = st.stx_size;
> +	}
> +#endif

As in fchmodat, etc., save the st[x]_size field in the #ifdef block
and get the common code out so it's not duplicated.

Rich

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

* Re: [musl] [PATCH 07/14] Emulate wait4 using waitid
  2020-09-03 15:49   ` Rich Felker
@ 2020-09-03 16:25     ` Stefan O'Rear
  2020-09-03 16:38       ` Rich Felker
  0 siblings, 1 reply; 31+ messages in thread
From: Stefan O'Rear @ 2020-09-03 16:25 UTC (permalink / raw)
  To: musl



On Thu, Sep 3, 2020, at 11:49 AM, Rich Felker wrote:
> On Thu, Sep 03, 2020 at 07:23:02AM -0400, Stefan O'Rear wrote:
> > riscv32 and future architectures lack wait4.
> > ---
> >  src/internal/wait4_waitid.h |  1 +
> >  src/linux/__wait4_waitid.c  | 52 +++++++++++++++++++++++++++++++++++++
> >  src/linux/wait4.c           |  5 ++++
> >  src/process/waitpid.c       |  6 +++++
> >  src/stdio/pclose.c          |  6 +++++
> >  src/unistd/faccessat.c      |  6 ++++-
> >  6 files changed, 75 insertions(+), 1 deletion(-)
> >  create mode 100644 src/internal/wait4_waitid.h
> >  create mode 100644 src/linux/__wait4_waitid.c
> 
> I really don't like introducing a new src/internal file for this. If

I agree.

> the code needs to be shared it should probably just be in wait4.c,
> renamed to __wait4, declared in src/include/sys/wait.h according to
> the usual pattern for exposing namespace-safe versions of
> namespace-violating functions.

Currently waitpid and waitid are cancellation points (required by POSIX)
but wait4 is not, which is why I did not have anything else call a function
with exactly wait4 semantics.

> Ideally I'd like to just not need it, but I'm not sure that's
> possible:
> 
> - faccessat throws away the status and doesn't have any need for the
>   status or idtype emulation code. It could easily be just different
>   syscalls in #ifdef/#else paths.

I think that is exactly what my patch does?

> - pclose does need status but not the idtype part. but it's only
>   listening for process termination not all the other weird stuff. I'm
>   not sure if it would make sense to construct status inline here. It
>   might if we had a macro like the glibc "inverse-W" macro (I forget
>   its name) to construct a wait status from parts; if so this could
>   later be considered for a public API (previously requested).

Earlier I had the wait status conversion code broken out separately
but it seemed not worth it for just pclose.

> - waitpid and wait4 at least need the idtype and status construction.
> 
> Unfortunately, wait4 also needs the rusage conversion, which waitpid
> doesn't want. This kinda defeats my idea of just exposing __wait4 from
> wait4.c.
> 
> A side observation to keep in mind is that passing the argument cp
> doesn't really help optimize anything; it only worked well in
> c2feda4e2e because the function there is inline. Of the 4 callers you
> have, faccessat and pclose have hard requirements not to be a
> cancellation point and waitpid has a hard requirement to be one. But

pclose has a hard requirement to not be a cancellation point but it also
has "If a thread is canceled during execution of pclose(), the behavior
is undefined."  The implications of the combination are confusing.

> if the function weren't used for the former, it could just always be
> cancellable -- wait4 probably should have been cancellable all along,
> and almost surely is on other implementations, so to use it safely
> you'd have to not use, block, or handle cancellation.

I have no immediate objection to making wait4 a cancellation point but
I would prefer to make that change consistently on all architectures.
I don't have a good sense of who uses cancellation and wait4 and what
compatibility constraints are imposed by code (as opposed to standards).

> So I'm leaning towards sticking with something like what you've done,
> but with declaration moved to src/include/sys/wait.h, or possibly
> src/internal/syscall.h (since it's essentially emulation of a

I'd be very happy to not have a one-line header file.  I looked at syscall.h
earlier but wasn't sure if it fit; I did not consider reserved namespace in
a public header (would this preclude use of hidden?).

Is src/linux/__exact_name_of_function.c the appropriate name for the file?

> syscall). Inline in src/internal/syscall.h might also be an option;
> one appealing aspect of that is that it would get rid of the #ifdefs
> in source files and allow calling __sys_wait4() unconditionally with
> no codegen regression on existing archs. This is analogous to
> __sys_open[23].
> 
> Rich

-s

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

* Re: [musl] [PATCH 07/14] Emulate wait4 using waitid
  2020-09-03 16:25     ` Stefan O'Rear
@ 2020-09-03 16:38       ` Rich Felker
  0 siblings, 0 replies; 31+ messages in thread
From: Rich Felker @ 2020-09-03 16:38 UTC (permalink / raw)
  To: musl

On Thu, Sep 03, 2020 at 12:25:19PM -0400, Stefan O'Rear wrote:
> 
> 
> On Thu, Sep 3, 2020, at 11:49 AM, Rich Felker wrote:
> > On Thu, Sep 03, 2020 at 07:23:02AM -0400, Stefan O'Rear wrote:
> > > riscv32 and future architectures lack wait4.
> > > ---
> > >  src/internal/wait4_waitid.h |  1 +
> > >  src/linux/__wait4_waitid.c  | 52 +++++++++++++++++++++++++++++++++++++
> > >  src/linux/wait4.c           |  5 ++++
> > >  src/process/waitpid.c       |  6 +++++
> > >  src/stdio/pclose.c          |  6 +++++
> > >  src/unistd/faccessat.c      |  6 ++++-
> > >  6 files changed, 75 insertions(+), 1 deletion(-)
> > >  create mode 100644 src/internal/wait4_waitid.h
> > >  create mode 100644 src/linux/__wait4_waitid.c
> > 
> > I really don't like introducing a new src/internal file for this. If
> 
> I agree.
> 
> > the code needs to be shared it should probably just be in wait4.c,
> > renamed to __wait4, declared in src/include/sys/wait.h according to
> > the usual pattern for exposing namespace-safe versions of
> > namespace-violating functions.
> 
> Currently waitpid and waitid are cancellation points (required by POSIX)
> but wait4 is not, which is why I did not have anything else call a function
> with exactly wait4 semantics.
> 
> > Ideally I'd like to just not need it, but I'm not sure that's
> > possible:
> > 
> > - faccessat throws away the status and doesn't have any need for the
> >   status or idtype emulation code. It could easily be just different
> >   syscalls in #ifdef/#else paths.
> 
> I think that is exactly what my patch does?

Yes, sorry I missed that. I think I saw the other three and just
assumed this one was the same since it was part of the same patch.

> > - pclose does need status but not the idtype part. but it's only
> >   listening for process termination not all the other weird stuff. I'm
> >   not sure if it would make sense to construct status inline here. It
> >   might if we had a macro like the glibc "inverse-W" macro (I forget
> >   its name) to construct a wait status from parts; if so this could
> >   later be considered for a public API (previously requested).
> 
> Earlier I had the wait status conversion code broken out separately
> but it seemed not worth it for just pclose.
> 
> > - waitpid and wait4 at least need the idtype and status construction.
> > 
> > Unfortunately, wait4 also needs the rusage conversion, which waitpid
> > doesn't want. This kinda defeats my idea of just exposing __wait4 from
> > wait4.c.
> > 
> > A side observation to keep in mind is that passing the argument cp
> > doesn't really help optimize anything; it only worked well in
> > c2feda4e2e because the function there is inline. Of the 4 callers you
> > have, faccessat and pclose have hard requirements not to be a
> > cancellation point and waitpid has a hard requirement to be one. But
> 
> pclose has a hard requirement to not be a cancellation point but it also
> has "If a thread is canceled during execution of pclose(), the behavior
> is undefined."  The implications of the combination are confusing.

It's an optional cancellation point, but if cancelled the side effects
must be correct. Since the FILE and underlying fd have already been
closed at this point, it's too late for cancellation to be acted upon;
any thing you do would leave the process in an inconsistent state,
where the caller has to assume the FILE is still valid and thus
performs UAF/DF if it does anything with it.

Note that you can't swap the order of the fd close and wait because
the child very well may not exit until the pipe is closed.

So, the only valid way pclose could act on cancellation is before
taking any action. This is almost surely not what was intended in the
standard, since it's useles, but the conclusion here is just that
nobody thought about this stuff enough to realize that allowing pclose
to be a cancellation point was fundamentally wrong.

> > if the function weren't used for the former, it could just always be
> > cancellable -- wait4 probably should have been cancellable all along,
> > and almost surely is on other implementations, so to use it safely
> > you'd have to not use, block, or handle cancellation.
> 
> I have no immediate objection to making wait4 a cancellation point but
> I would prefer to make that change consistently on all architectures.
> I don't have a good sense of who uses cancellation and wait4 and what
> compatibility constraints are imposed by code (as opposed to standards).

Yes, it should be done consistently and as a separate patch if we go
this way.

> > So I'm leaning towards sticking with something like what you've done,
> > but with declaration moved to src/include/sys/wait.h, or possibly
> > src/internal/syscall.h (since it's essentially emulation of a
> 
> I'd be very happy to not have a one-line header file.  I looked at syscall.h
> earlier but wasn't sure if it fit; I did not consider reserved namespace in
> a public header (would this preclude use of hidden?).

src/include/* are not public headers, but wrappers around the public
headers to add namespace-protected versions of functions etc. However
since this is really not a "version of wait4" but an "emulation of
SYS_wait4", it probably makes more sense to put it in
internal/syscall.h, just like __sys_open[23]. That doesn't mean it has
to be inline, just that the declaration could go there, and a macro to
just use __syscall(SYS_wait4...) directly if it exists which would
keep some small amount of #ifdef out of source files.

> Is src/linux/__exact_name_of_function.c the appropriate name for the file?

If there's an external source file still, I'd put it in
src/process/__function_name.c or src/internal/... like you did. The
existing naming here is not entirely consistent, but generally,
src/subsystem/__internal_function.c is an internal function for
implementing that subsystem/family, not an internal functon used by
other subsystems that just happens to mostly-match a public function
in that subsystem.

src/internal is a kinda sloppy mix of things, but is mostly internal
functions that are shared between two or more subsystems.

Rich

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

* Re: [musl] [PATCH 07/14] Emulate wait4 using waitid
  2020-09-03 15:40       ` Stefan O'Rear
@ 2020-09-03 18:08         ` Arnd Bergmann
  0 siblings, 0 replies; 31+ messages in thread
From: Arnd Bergmann @ 2020-09-03 18:08 UTC (permalink / raw)
  To: musl

On Thu, Sep 3, 2020 at 5:41 PM Stefan O'Rear <sorear@fastmail.com> wrote:
>
> On Thu, Sep 3, 2020, at 11:36 AM, Arnd Bergmann wrote:
> > On Thu, Sep 3, 2020 at 4:56 PM Stefan O'Rear <sorear@fastmail.com> wrote:
> > >
> > > On Thu, Sep 3, 2020, at 7:23 AM, Stefan O'Rear wrote:
> > > > +             case CLD_STOPPED:
> > > > +             case CLD_TRAPPED:
> > > > +                     sw = ((info.si_status&0xff) << 8) + 0x7f;
> > > > +                     break;
> > >
> > > This is trying to be defensive but it is the cause of the strace issue
> > > in the cover letter since the ptrace interface generates si_status
> > > greater than 8 bits which must be visible in WSTOPSIG; the v2 will not
> > > mask here.
> >
> > Ah, I was trying to find out what exactly the masking was for since
> > I did not have that in my original version of the same function for Arm:
>
> Where is this coming from?  I didn't want to blindly copy code from glibc
> and I couldn't find any documentation of how the mapping is supposed
> to work other than the POSIX descriptions of the wait and waitid functions
> (which is why I missed the non-POSIX ptrace cases).
>
> If there's an authoritative description of the mapping I would like to match
> it exactly.

I did this prototype implementation to test the syscall changes before
I submitted them into the mainline kernel:
https://git.linaro.org/people/arnd.bergmann/musl-y2038.git/

This was never meant to get merged, but I made sure that I could
get LTP to pass just using the new minimum set of syscalls.

       Arnd

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

* Re: [musl] [PATCH 05/14] Add src/internal/statx.h
  2020-09-03 15:51     ` Rich Felker
@ 2020-09-03 18:08       ` Arnd Bergmann
  0 siblings, 0 replies; 31+ messages in thread
From: Arnd Bergmann @ 2020-09-03 18:08 UTC (permalink / raw)
  To: musl

On Thu, Sep 3, 2020 at 5:51 PM Rich Felker <dalias@libc.org> wrote:
> On Thu, Sep 03, 2020 at 05:39:51PM +0200, Arnd Bergmann wrote:
> > On Thu, Sep 3, 2020 at 1:24 PM Stefan O'Rear <sorear@fastmail.com> wrote:
> >
> > Unrelated to your patch that just moves this, I notice that
> > the kernel version has gained an stx_mnt_id field.
>
> This could potentially be added, but should be a separate change, and
> really only makes sense if/when we put this in a public header since
> nothing internal is using it.

Agreed to all of those, I just mentioned it when I noticed the difference.

     Arnd

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

* Re: [musl] [PATCH 02/14] time64: Don't make aliases to nonexistent syscalls
  2020-09-03 15:56   ` Rich Felker
@ 2020-09-03 19:36     ` Stefan O'Rear
  2020-09-03 21:17       ` Rich Felker
  0 siblings, 1 reply; 31+ messages in thread
From: Stefan O'Rear @ 2020-09-03 19:36 UTC (permalink / raw)
  To: musl

On Thu, Sep 3, 2020, at 11:56 AM, Rich Felker wrote:
> On Thu, Sep 03, 2020 at 07:22:57AM -0400, Stefan O'Rear wrote:
> > riscv32 and future architectures lack the _time32 variants entirely, so
> > don't try to use their numbers.
> > ---
> >  src/internal/syscall.h | 2 ++
> >  1 file changed, 2 insertions(+)
> > 
> > diff --git a/src/internal/syscall.h b/src/internal/syscall.h
> > index d5f294d4..66fc4e5c 100644
> > --- a/src/internal/syscall.h
> > +++ b/src/internal/syscall.h
> > @@ -201,6 +201,7 @@ static inline long __alt_socketcall(int sys, int sock, int cp, long a, long b, l
> >  #define SYS_sendfile SYS_sendfile64
> >  #endif
> >  
> > +#ifdef SYS_timer_settime32
> >  #ifndef SYS_timer_settime
> >  #define SYS_timer_settime SYS_timer_settime32
> >  #endif
> > @@ -240,6 +241,7 @@ static inline long __alt_socketcall(int sys, int sock, int cp, long a, long b, l
> >  #ifndef SYS_settimeofday
> >  #define SYS_settimeofday SYS_settimeofday_time32
> >  #endif
> > +#endif
> 
> The existing expectation internally in musl is that archs that lack
> legacy time32 syscalls have both the unadorned and _time64 macros
> defined to the same value. The public headers don't have to be like
> that but the internal ones do. See arch/x32/syscall_arch.h which does
> it but in the opposite direction. This logic is all tested for x32 and
> a big part of the point of that was preparing for rv32 and future
> 32-bit archs.
> 
> I'm actually missing how this patch worked as-written, since for
> example timer_settime.c unconditionally assumes SYS_timer_settime is
> defined, and if it's defined to anything other than the same value as
> the time64 version, it will use the value as a fallback.

src/internal/syscall.h has two groups of conditional definitions of unadorned
syscall numbers, the first of which sets undefined syscalls to the _time32
version, the second of which sets to the _time64 version.  So for instance I
see no way for the #define SYS_clock_gettime SYS_clock_gettime64
(https://git.musl-libc.org/cgit/musl/tree/src/internal/syscall.h#n250) to execute.

-s

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

* Re: [musl] [PATCH 02/14] time64: Don't make aliases to nonexistent syscalls
  2020-09-03 19:36     ` Stefan O'Rear
@ 2020-09-03 21:17       ` Rich Felker
  0 siblings, 0 replies; 31+ messages in thread
From: Rich Felker @ 2020-09-03 21:17 UTC (permalink / raw)
  To: musl

On Thu, Sep 03, 2020 at 03:36:00PM -0400, Stefan O'Rear wrote:
> On Thu, Sep 3, 2020, at 11:56 AM, Rich Felker wrote:
> > On Thu, Sep 03, 2020 at 07:22:57AM -0400, Stefan O'Rear wrote:
> > > riscv32 and future architectures lack the _time32 variants entirely, so
> > > don't try to use their numbers.
> > > ---
> > >  src/internal/syscall.h | 2 ++
> > >  1 file changed, 2 insertions(+)
> > > 
> > > diff --git a/src/internal/syscall.h b/src/internal/syscall.h
> > > index d5f294d4..66fc4e5c 100644
> > > --- a/src/internal/syscall.h
> > > +++ b/src/internal/syscall.h
> > > @@ -201,6 +201,7 @@ static inline long __alt_socketcall(int sys, int sock, int cp, long a, long b, l
> > >  #define SYS_sendfile SYS_sendfile64
> > >  #endif
> > >  
> > > +#ifdef SYS_timer_settime32
> > >  #ifndef SYS_timer_settime
> > >  #define SYS_timer_settime SYS_timer_settime32
> > >  #endif
> > > @@ -240,6 +241,7 @@ static inline long __alt_socketcall(int sys, int sock, int cp, long a, long b, l
> > >  #ifndef SYS_settimeofday
> > >  #define SYS_settimeofday SYS_settimeofday_time32
> > >  #endif
> > > +#endif
> > 
> > The existing expectation internally in musl is that archs that lack
> > legacy time32 syscalls have both the unadorned and _time64 macros
> > defined to the same value. The public headers don't have to be like
> > that but the internal ones do. See arch/x32/syscall_arch.h which does
> > it but in the opposite direction. This logic is all tested for x32 and
> > a big part of the point of that was preparing for rv32 and future
> > 32-bit archs.
> > 
> > I'm actually missing how this patch worked as-written, since for
> > example timer_settime.c unconditionally assumes SYS_timer_settime is
> > defined, and if it's defined to anything other than the same value as
> > the time64 version, it will use the value as a fallback.
> 
> src/internal/syscall.h has two groups of conditional definitions of unadorned
> syscall numbers, the first of which sets undefined syscalls to the _time32
> version, the second of which sets to the _time64 version.  So for instance I
> see no way for the #define SYS_clock_gettime SYS_clock_gettime64
> (https://git.musl-libc.org/cgit/musl/tree/src/internal/syscall.h#n250) to execute.

OK, I think I see what happened. Originally 4bbd7baea7 was done with
the intent that riscv32 and future 32-bit archs would not need to do
their own definitions of the unadorned syscall names in terms of the
time64 ones, and when committed it would have worked. However, later
5a105f19b5 and 2cae9f59da hid the old syscalls that were unable to be
used safely in applictions, but at risk of being used as such, behind
_time32 renamings, and broke the intended mechanism.

As such, your patch does get around the problem and make the right
definitions exposed, but I don't really like that it conditions them
all on a single #ifdef SYS_timer_settime32. If we want to keep the
property that rv32 and future archs aren't required to define the
unadorned names themselves (maybe they'd want to for the sake of
public headers anyway, but I'm not sure about this still; I think we
need it at least for futex), a solution I like somewhat better would
be along the lines of:

-#ifndef SYS_timer_settime
+#ifdef SYS_timer_settime32

for each of the affected syscalls. This would also have the nice
effect of producing an error if there already was a conflicting
definition where the unadorned and time32 names both exist but don't
match.

Rich

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

* Re: [musl] [PATCH 06/14] Only call fstatat if defined
  2020-09-03 16:05   ` Rich Felker
@ 2020-09-04  1:47     ` Stefan O'Rear
  0 siblings, 0 replies; 31+ messages in thread
From: Stefan O'Rear @ 2020-09-04  1:47 UTC (permalink / raw)
  To: musl

On Thu, Sep 3, 2020, at 12:05 PM, Rich Felker wrote:
> On Thu, Sep 03, 2020 at 07:23:01AM -0400, Stefan O'Rear wrote:
> > +		r = __syscall(SYS_statx, AT_FDCWD, s, AT_SYMLINK_NOFOLLOW, 0,
> > +			&(struct statx){0});
> > +#endif
> >  #endif
> 
> Can be #elif. Also, is zero request mask ok here?

The manpage doesn't say it's not ok.

-s

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

end of thread, other threads:[~2020-09-04  1:48 UTC | newest]

Thread overview: 31+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-09-03 11:22 [musl] [PATCH 00/14] riscv32 support Stefan O'Rear
2020-09-03 11:22 ` [musl] [PATCH 01/14] Remove ARMSUBARCH relic from configure Stefan O'Rear
2020-09-03 11:22 ` [musl] [PATCH 02/14] time64: Don't make aliases to nonexistent syscalls Stefan O'Rear
2020-09-03 15:56   ` Rich Felker
2020-09-03 19:36     ` Stefan O'Rear
2020-09-03 21:17       ` Rich Felker
2020-09-03 11:22 ` [musl] [PATCH 03/14] time64: Only getrlimit/setrlimit if they exist Stefan O'Rear
2020-09-03 11:22 ` [musl] [PATCH 04/14] time64: Only gettimeofday/settimeofday if exist Stefan O'Rear
2020-09-03 11:23 ` [musl] [PATCH 05/14] Add src/internal/statx.h Stefan O'Rear
2020-09-03 15:39   ` Arnd Bergmann
2020-09-03 15:51     ` Rich Felker
2020-09-03 18:08       ` Arnd Bergmann
2020-09-03 11:23 ` [musl] [PATCH 06/14] Only call fstatat if defined Stefan O'Rear
2020-09-03 16:05   ` Rich Felker
2020-09-04  1:47     ` Stefan O'Rear
2020-09-03 11:23 ` [musl] [PATCH 07/14] Emulate wait4 using waitid Stefan O'Rear
2020-09-03 14:56   ` Stefan O'Rear
2020-09-03 15:36     ` Arnd Bergmann
2020-09-03 15:40       ` Stefan O'Rear
2020-09-03 18:08         ` Arnd Bergmann
2020-09-03 15:49   ` Rich Felker
2020-09-03 16:25     ` Stefan O'Rear
2020-09-03 16:38       ` Rich Felker
2020-09-03 11:23 ` [musl] [PATCH 08/14] riscv: Fall back to syscall __riscv_flush_icache Stefan O'Rear
2020-09-03 11:23 ` [musl] [PATCH 09/14] riscv32: Target and subtarget detection Stefan O'Rear
2020-09-03 11:23 ` [musl] [PATCH 10/14] riscv32: add arch headers Stefan O'Rear
2020-09-03 15:49   ` Arnd Bergmann
2020-09-03 11:23 ` [musl] [PATCH 11/14] riscv32: Add fenv and math Stefan O'Rear
2020-09-03 11:23 ` [musl] [PATCH 12/14] riscv32: Add dlsym Stefan O'Rear
2020-09-03 11:23 ` [musl] [PATCH 13/14] riscv32: Add jmp_buf and sigreturn Stefan O'Rear
2020-09-03 11:23 ` [musl] [PATCH 14/14] riscv32: Add thread support Stefan O'Rear

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