[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <0976471a36cd4facf712bc02e733f669f1697083.1687976753.git.falcon@tinylab.org>
Date: Thu, 29 Jun 2023 02:53:18 +0800
From: Zhangjin Wu <falcon@...ylab.org>
To: thomas@...ch.de, w@....eu
Cc: falcon@...ylab.org, arnd@...db.de, linux-kernel@...r.kernel.org,
linux-kselftest@...r.kernel.org, linux-riscv@...ts.infradead.org
Subject: [PATCH v1 02/11] tools/nolibc: add new crt.h with _start_c
As the environ and _auxv support added for nolibc, the assembly _start
function becomes more and more complex and therefore makes the porting
of nolibc to new architectures harder and harder.
To simplify portability, this crt.h is added to do most of the assembly
start operations in C function: _start_c(), which reduces the complexity
a lot and will eventually simplify the porting of nolibc to the new
architectures.
The new _start_c() only requires a stack pointer argument, it will find
argv, envp and _auxv for us, and then call main(), finally, it exit()
with main's return status. With this new _start_c(), the future new
architectures only require to add very few assembly instructions.
It may also easier the future init/fini support.
Signed-off-by: Zhangjin Wu <falcon@...ylab.org>
---
tools/include/nolibc/crt.h | 57 ++++++++++++++++++++++++++++++++++++++
1 file changed, 57 insertions(+)
create mode 100644 tools/include/nolibc/crt.h
diff --git a/tools/include/nolibc/crt.h b/tools/include/nolibc/crt.h
new file mode 100644
index 000000000000..698fe1084d26
--- /dev/null
+++ b/tools/include/nolibc/crt.h
@@ -0,0 +1,57 @@
+/* SPDX-License-Identifier: LGPL-2.1 OR MIT */
+/*
+ * C Run Time support for NOLIBC
+ * Copyright (C) 2023 Zhangjin Wu <falcon@...ylab.org>
+ */
+
+#ifndef _NOLIBC_CRT_H
+#define _NOLIBC_CRT_H
+
+char **environ __attribute__((weak));
+const unsigned long *_auxv __attribute__((weak));
+
+int main(int argc, char *argv[], char **envp);
+static void exit(int);
+
+void _start_c(long *sp)
+{
+ int argc, i;
+ char **argv;
+ char **envp;
+
+ /*
+ * sp : argc <-- argument count, required by main()
+ * argv: argv[0] <-- argument vector, required by main()
+ * argv[1]
+ * ...
+ * argv[argc-1]
+ * null
+ * envp: envp[0] <-- environment variables, required by main() and getenv()
+ * envp[1]
+ * ...
+ * null
+ * _auxv: auxv[0] <-- auxiliary vector, required by getauxval()
+ * auxv[1]
+ * ...
+ * null
+ */
+
+ /* assign argc and argv */
+ argc = sp[0];
+ argv = (void *)(sp + 1);
+
+ /* find envp */
+ envp = argv + argc + 1;
+ environ = envp;
+
+ /* find auxv */
+ i = 0;
+ while (envp[i])
+ i++;
+ _auxv = (void *)(envp + i + 1);
+
+ /* go to application */
+ exit(main(argc, argv, envp));
+}
+
+#endif /* _NOLIBC_CRT_H */
--
2.25.1
Powered by blists - more mailing lists