From d5ad39f450942fd259e963a4a264192d1a4f4ac3 Mon Sep 17 00:00:00 2001
From: Pavel Pisa <pisa@cmp.felk.cvut.cz>
Date: Mon, 21 Nov 2022 15:38:48 +0100
Subject: [PATCH] seminaries/qtrvsim/os-emu-example: remap open(at) flags to
 kernel from library defined ones

This allows to compile and run on Linux kernel even binaries
even binaries linked even with C library build for embedded
targets (bare metal riscv32-unknown-elf or riscv64-unknown-elf
NewLib is usable then).

Signed-off-by: Pavel Pisa <pisa@cmp.felk.cvut.cz>
---
 .../qtrvsim/os-emu-example/qtrvsim_sys_stub.c | 80 ++++++++++++++++++-
 1 file changed, 78 insertions(+), 2 deletions(-)

diff --git a/seminaries/qtrvsim/os-emu-example/qtrvsim_sys_stub.c b/seminaries/qtrvsim/os-emu-example/qtrvsim_sys_stub.c
index 22c2b04..e56603e 100644
--- a/seminaries/qtrvsim/os-emu-example/qtrvsim_sys_stub.c
+++ b/seminaries/qtrvsim/os-emu-example/qtrvsim_sys_stub.c
@@ -16,6 +16,33 @@
 
 #define UNUSED_PARAM(symbol) ((void)(symbol))
 
+
+/* Open flags definition for Linux kernel copied from musl-libc */
+
+#define KERNEL_O_CREAT        0100
+#define KERNEL_O_EXCL         0200
+#define KERNEL_O_NOCTTY       0400
+#define KERNEL_O_TRUNC       01000
+#define KERNEL_O_APPEND      02000
+#define KERNEL_O_NONBLOCK    04000
+#define KERNEL_O_DSYNC      010000
+#define KERNEL_O_SYNC     04010000
+#define KERNEL_O_RSYNC    04010000
+#define KERNEL_O_DIRECTORY 0200000
+#define KERNEL_O_NOFOLLOW  0400000
+#define KERNEL_O_CLOEXEC  02000000
+
+#define KERNEL_O_PATH 010000000
+
+#define KERNEL_O_SYNC1 040000
+
+#define KERNEL_O_ACCMODE (03 | KERNEL_O_PATH)
+#define KERNEL_O_RDONLY 00
+#define KERNEL_O_WRONLY 01
+#define KERNEL_O_RDWR 02
+
+#define TARGET_AT_FDCWD -100
+
 /* Register name - works in collusion with the linker.  */
 register char * stack_ptr asm ("sp");
 
@@ -79,9 +106,58 @@ _openat (int fd, const char * path,
 	// use fd = -100 for normal open behaviour. Full openat not supported.
 	register int __a0 asm("a0") = fd;
 	register const char * __a1 asm("a1") = path;
-	register int __a2 asm("a2") = flags;
+	register int __a2 asm("a2") = 0;
 	register int __a3 asm("a3");
 
+#ifdef O_CREAT
+	if (flags & O_CREAT)
+		__a2 |= KERNEL_O_CREAT;
+#endif
+#ifdef O_EXCL
+	if (flags & O_EXCL)
+		__a2 |= KERNEL_O_EXCL;
+#endif
+#ifdef O_NOCTTY
+	if (flags & O_NOCTTY)
+		__a2 |= KERNEL_O_NOCTTY;
+#endif
+#ifdef O_TRUNC
+	if (flags & O_TRUNC)
+		__a2 |= KERNEL_O_TRUNC;
+#endif
+#ifdef O_APPEND
+	if (flags & O_APPEND)
+		__a2 |= KERNEL_O_APPEND;
+#endif
+#ifdef O_NONBLOCK
+	if (flags & O_NONBLOCK)
+		__a2 |= KERNEL_O_NONBLOCK;
+#endif
+#ifdef O_DSYNC
+	if (flags & O_DSYNC)
+		__a2 |= KERNEL_O_DSYNC;
+#endif
+#ifdef O_SYNC
+	if (flags & O_SYNC)
+		__a2 |= KERNEL_O_SYNC;
+#endif
+#ifdef O_RSYNC
+	if (flags & O_RSYNC)
+		__a2 |= KERNEL_O_RSYNC;
+#endif
+#ifdef O_DIRECTORY
+	if (flags & O_DIRECTORY)
+		__a2 |= KERNEL_O_DIRECTORY;
+#endif
+#ifdef O_NOFOLLOW
+	if (flags & O_NOFOLLOW)
+		__a2 |= KERNEL_O_NOFOLLOW;
+#endif
+#ifdef O_CLOEXEC
+	if (flags & O_CLOEXEC)
+		__a2 |= KERNEL_O_CLOEXEC;
+#endif
+
 	if (flags & O_CREAT) {
 		va_list list;
 		va_start(list, flags);
@@ -328,7 +404,7 @@ _off_t _lseek_r(struct _reent *reent, int file, _off_t pos, int dir)
 
 int _open_r(struct _reent *reent, const char *path, int flags, int opts);
 int _open_r(struct _reent *reent, const char *path, int flags, int opts)
-{ UNUSED_PARAM(reent); return _openat(-100, path, flags, opts);}
+{ UNUSED_PARAM(reent); return _openat(TARGET_AT_FDCWD, path, flags, opts);}
 
 int _openat_r(struct _reent *reent, int fd, const char *path, int flags, int opts);
 int _openat_r(struct _reent *reent, int fd, const char *path, int flags, int opts)
-- 
GitLab