Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

rebase musllibc on top of upstream master #19

Open
axel-h opened this issue Jul 5, 2022 · 7 comments
Open

rebase musllibc on top of upstream master #19

axel-h opened this issue Jul 5, 2022 · 7 comments

Comments

@axel-h
Copy link
Member

axel-h commented Jul 5, 2022

Follow-up from a Mattermost suggestion from @kent-mcleod: rebase musllibc on top of upstream master. Might be worth trying a merge commit there to have sychronization point again.

@wom-bat
Copy link
Member

wom-bat commented Dec 6, 2022

Please can we do this! libmuslc doesn't currently build with gcc-12; the upstream source does.

@axel-h
Copy link
Member Author

axel-h commented Dec 7, 2022

@wom-bat: can you make a PR for this?

@wom-bat
Copy link
Member

wom-bat commented Dec 7, 2022

I'll try.
I'm extremely short of time at the moment...

@wom-bat
Copy link
Member

wom-bat commented Dec 7, 2022

I've created a branch to work on.

@kent-mcleod
Copy link
Member

I started working on something similar a few weeks ago. It's probably cleaner to do a fresh fork on top of a recent libmusl version. Things that I would change about a fresh port would be not creating separate sel4 architectures (eg arm_sel4) and instead just change the original architecture code. This simplifies the amount of changes required to add seL4 support. It means that the original architectures don't work, but because there also ends up being seL4-specific changes to common code the original Linux support already isn't preserved.

Upstream musl doesn't yet have support for rv32 (although they have it on a roadmap it's not scheduled), and our support for riscv was added before support for rv64 was added upstream. Our support should probably be removed, and replaced with the upstream port.

Upstream musl's malloc has a new implementation. The new implementation uses mmap differently, and the basic support provided by libsel4muslcsys isn't enough. It is possible to currently use the old malloc implementation with a configuration flag when building musl.

I've attached a commit that I was using on top of the most recent musl release 1.2.3 [1]. It appeared sufficient to start with.

[1]

From 51b1907fcac40cbb84d39f59e41921294b7219b8 Mon Sep 17 00:00:00 2001
From: Kent McLeod <[email protected]>
Date: Thu, 17 Nov 2022 14:07:34 +1100
Subject: [PATCH] syscall: Replace all syscalls to call __sysinfo

aarch64, arm, i386 and x86_64.
---
 arch/aarch64/syscall_arch.h | 69 +++++++---------------------
 arch/arm/syscall_arch.h     | 90 +++++++------------------------------
 arch/i386/syscall_arch.h    | 64 ++++----------------------
 arch/x86_64/syscall_arch.h  | 65 ++++++++-------------------
 4 files changed, 59 insertions(+), 229 deletions(-)

diff --git a/arch/aarch64/syscall_arch.h b/arch/aarch64/syscall_arch.h
index 504983aa2..514b28612 100644
--- a/arch/aarch64/syscall_arch.h
+++ b/arch/aarch64/syscall_arch.h
@@ -1,78 +1,41 @@
 #define __SYSCALL_LL_E(x) (x)
 #define __SYSCALL_LL_O(x) (x)
 
-#define __asm_syscall(...) do { \
-	__asm__ __volatile__ ( "svc 0" \
-	: "=r"(x0) : __VA_ARGS__ : "memory", "cc"); \
-	return x0; \
-	} while (0)
+extern unsigned long __sysinfo;
+
+#define CALL_SYSINFO(n, ...) ((long(*)(long,...))__sysinfo)(n, ##__VA_ARGS__)
 
 static inline long __syscall0(long n)
 {
-	register long x8 __asm__("x8") = n;
-	register long x0 __asm__("x0");
-	__asm_syscall("r"(x8));
+    return CALL_SYSINFO(n);
 }
 
-static inline long __syscall1(long n, long a)
+static inline long __syscall1(long n, long a1)
 {
-	register long x8 __asm__("x8") = n;
-	register long x0 __asm__("x0") = a;
-	__asm_syscall("r"(x8), "0"(x0));
+    return CALL_SYSINFO(n, a1);
 }
 
-static inline long __syscall2(long n, long a, long b)
+static inline long __syscall2(long n, long a1, long a2)
 {
-	register long x8 __asm__("x8") = n;
-	register long x0 __asm__("x0") = a;
-	register long x1 __asm__("x1") = b;
-	__asm_syscall("r"(x8), "0"(x0), "r"(x1));
+    return CALL_SYSINFO(n, a1, a2);
 }
 
-static inline long __syscall3(long n, long a, long b, long c)
+static inline long __syscall3(long n, long a1, long a2, long a3)
 {
-	register long x8 __asm__("x8") = n;
-	register long x0 __asm__("x0") = a;
-	register long x1 __asm__("x1") = b;
-	register long x2 __asm__("x2") = c;
-	__asm_syscall("r"(x8), "0"(x0), "r"(x1), "r"(x2));
+    return CALL_SYSINFO(n, a1, a2, a3);
 }
 
-static inline long __syscall4(long n, long a, long b, long c, long d)
+static inline long __syscall4(long n, long a1, long a2, long a3, long a4)
 {
-	register long x8 __asm__("x8") = n;
-	register long x0 __asm__("x0") = a;
-	register long x1 __asm__("x1") = b;
-	register long x2 __asm__("x2") = c;
-	register long x3 __asm__("x3") = d;
-	__asm_syscall("r"(x8), "0"(x0), "r"(x1), "r"(x2), "r"(x3));
+    return CALL_SYSINFO(n, a1, a2, a3, a4);
 }
 
-static inline long __syscall5(long n, long a, long b, long c, long d, long e)
+static inline long __syscall5(long n, long a1, long a2, long a3, long a4, long a5)
 {
-	register long x8 __asm__("x8") = n;
-	register long x0 __asm__("x0") = a;
-	register long x1 __asm__("x1") = b;
-	register long x2 __asm__("x2") = c;
-	register long x3 __asm__("x3") = d;
-	register long x4 __asm__("x4") = e;
-	__asm_syscall("r"(x8), "0"(x0), "r"(x1), "r"(x2), "r"(x3), "r"(x4));
+    return CALL_SYSINFO(n, a1, a2, a3, a4, a5);
 }
 
-static inline long __syscall6(long n, long a, long b, long c, long d, long e, long f)
+static inline long __syscall6(long n, long a1, long a2, long a3, long a4, long a5, long a6)
 {
-	register long x8 __asm__("x8") = n;
-	register long x0 __asm__("x0") = a;
-	register long x1 __asm__("x1") = b;
-	register long x2 __asm__("x2") = c;
-	register long x3 __asm__("x3") = d;
-	register long x4 __asm__("x4") = e;
-	register long x5 __asm__("x5") = f;
-	__asm_syscall("r"(x8), "0"(x0), "r"(x1), "r"(x2), "r"(x3), "r"(x4), "r"(x5));
+    return CALL_SYSINFO(n, a1, a2, a3, a4, a5, a6);
 }
-
-#define VDSO_USEFUL
-#define VDSO_CGT_SYM "__kernel_clock_gettime"
-#define VDSO_CGT_VER "LINUX_2.6.39"
-
-#define IPC_64 0
diff --git a/arch/arm/syscall_arch.h b/arch/arm/syscall_arch.h
index a877b2cff..9a95a3cdc 100644
--- a/arch/arm/syscall_arch.h
+++ b/arch/arm/syscall_arch.h
@@ -3,101 +3,43 @@
 ((union { long long ll; long l[2]; }){ .ll = x }).l[1]
 #define __SYSCALL_LL_O(x) 0, __SYSCALL_LL_E((x))
 
-#ifdef __thumb__
+extern unsigned int __sysinfo;
 
-/* Avoid use of r7 in asm constraints when producing thumb code,
- * since it's reserved as frame pointer and might not be supported. */
-#define __ASM____R7__
-#define __asm_syscall(...) do { \
-	__asm__ __volatile__ ( "mov %1,r7 ; mov r7,%2 ; svc 0 ; mov r7,%1" \
-	: "=r"(r0), "=&r"((int){0}) : __VA_ARGS__ : "memory"); \
-	return r0; \
-	} while (0)
-
-#else
-
-#define __ASM____R7__ __asm__("r7")
-#define __asm_syscall(...) do { \
-	__asm__ __volatile__ ( "svc 0" \
-	: "=r"(r0) : __VA_ARGS__ : "memory"); \
-	return r0; \
-	} while (0)
-#endif
-
-/* For thumb2, we can allow 8-bit immediate syscall numbers, saving a
- * register in the above dance around r7. Does not work for thumb1 where
- * only movs, not mov, supports immediates, and we can't use movs because
- * it doesn't support high regs. */
-#ifdef __thumb2__
-#define R7_OPERAND "rI"(r7)
-#else
-#define R7_OPERAND "r"(r7)
-#endif
+#define CALL_SYSINFO(n, ...) (__sysinfo ? ((long(*)(long,...))__sysinfo)(n, ##__VA_ARGS__) : -1)
 
 static inline long __syscall0(long n)
 {
-	register long r7 __ASM____R7__ = n;
-	register long r0 __asm__("r0");
-	__asm_syscall(R7_OPERAND);
+    return CALL_SYSINFO(n);
 }
 
-static inline long __syscall1(long n, long a)
+static inline long __syscall1(long n, long a1)
 {
-	register long r7 __ASM____R7__ = n;
-	register long r0 __asm__("r0") = a;
-	__asm_syscall(R7_OPERAND, "0"(r0));
+    return CALL_SYSINFO(n, a1);
 }
 
-static inline long __syscall2(long n, long a, long b)
+static inline long __syscall2(long n, long a1, long a2)
 {
-	register long r7 __ASM____R7__ = n;
-	register long r0 __asm__("r0") = a;
-	register long r1 __asm__("r1") = b;
-	__asm_syscall(R7_OPERAND, "0"(r0), "r"(r1));
+    return CALL_SYSINFO(n, a1, a2);
 }
 
-static inline long __syscall3(long n, long a, long b, long c)
+static inline long __syscall3(long n, long a1, long a2, long a3)
 {
-	register long r7 __ASM____R7__ = n;
-	register long r0 __asm__("r0") = a;
-	register long r1 __asm__("r1") = b;
-	register long r2 __asm__("r2") = c;
-	__asm_syscall(R7_OPERAND, "0"(r0), "r"(r1), "r"(r2));
+    return CALL_SYSINFO(n, a1, a2, a3);
 }
 
-static inline long __syscall4(long n, long a, long b, long c, long d)
+static inline long __syscall4(long n, long a1, long a2, long a3, long a4)
 {
-	register long r7 __ASM____R7__ = n;
-	register long r0 __asm__("r0") = a;
-	register long r1 __asm__("r1") = b;
-	register long r2 __asm__("r2") = c;
-	register long r3 __asm__("r3") = d;
-	__asm_syscall(R7_OPERAND, "0"(r0), "r"(r1), "r"(r2), "r"(r3));
+    return CALL_SYSINFO(n, a1, a2, a3, a4);
 }
 
-static inline long __syscall5(long n, long a, long b, long c, long d, long e)
+static inline long __syscall5(long n, long a1, long a2, long a3, long a4, long a5)
 {
-	register long r7 __ASM____R7__ = n;
-	register long r0 __asm__("r0") = a;
-	register long r1 __asm__("r1") = b;
-	register long r2 __asm__("r2") = c;
-	register long r3 __asm__("r3") = d;
-	register long r4 __asm__("r4") = e;
-	__asm_syscall(R7_OPERAND, "0"(r0), "r"(r1), "r"(r2), "r"(r3), "r"(r4));
+    return CALL_SYSINFO(n, a1, a2, a3, a4, a5);
 }
 
-static inline long __syscall6(long n, long a, long b, long c, long d, long e, long f)
+static inline long __syscall6(long n, long a1, long a2, long a3, long a4, long a5, long a6)
 {
-	register long r7 __ASM____R7__ = n;
-	register long r0 __asm__("r0") = a;
-	register long r1 __asm__("r1") = b;
-	register long r2 __asm__("r2") = c;
-	register long r3 __asm__("r3") = d;
-	register long r4 __asm__("r4") = e;
-	register long r5 __asm__("r5") = f;
-	__asm_syscall(R7_OPERAND, "0"(r0), "r"(r1), "r"(r2), "r"(r3), "r"(r4), "r"(r5));
+    return CALL_SYSINFO(n, a1, a2, a3, a4, a5, a6);
 }
 
-#define SYSCALL_FADVISE_6_ARG
-
-#define SYSCALL_IPC_BROKEN_MODE
+#define SYSCALL_FADVISE_6_ARG
\ No newline at end of file
diff --git a/arch/i386/syscall_arch.h b/arch/i386/syscall_arch.h
index f92b7aa9f..36cd262cf 100644
--- a/arch/i386/syscall_arch.h
+++ b/arch/i386/syscall_arch.h
@@ -3,87 +3,41 @@
 ((union { long long ll; long l[2]; }){ .ll = x }).l[1]
 #define __SYSCALL_LL_O(x) __SYSCALL_LL_E((x))
 
-#if SYSCALL_NO_TLS
-#define SYSCALL_INSNS "int $128"
-#else
-#define SYSCALL_INSNS "call *%%gs:16"
-#endif
+extern unsigned int __sysinfo;
 
-#define SYSCALL_INSNS_12 "xchg %%ebx,%%edx ; " SYSCALL_INSNS " ; xchg %%ebx,%%edx"
-#define SYSCALL_INSNS_34 "xchg %%ebx,%%edi ; " SYSCALL_INSNS " ; xchg %%ebx,%%edi"
+#define CALL_SYSINFO(n, ...) ((long(*)(long,...))__sysinfo)(n, ##__VA_ARGS__)
 
 static inline long __syscall0(long n)
 {
-	unsigned long __ret;
-	__asm__ __volatile__ (SYSCALL_INSNS : "=a"(__ret) : "a"(n) : "memory");
-	return __ret;
+    return CALL_SYSINFO(n);
 }
 
 static inline long __syscall1(long n, long a1)
 {
-	unsigned long __ret;
-	__asm__ __volatile__ (SYSCALL_INSNS_12 : "=a"(__ret) : "a"(n), "d"(a1) : "memory");
-	return __ret;
+    return CALL_SYSINFO(n, a1);
 }
 
 static inline long __syscall2(long n, long a1, long a2)
 {
-	unsigned long __ret;
-	__asm__ __volatile__ (SYSCALL_INSNS_12 : "=a"(__ret) : "a"(n), "d"(a1), "c"(a2) : "memory");
-	return __ret;
+    return CALL_SYSINFO(n, a1, a2);
 }
 
 static inline long __syscall3(long n, long a1, long a2, long a3)
 {
-	unsigned long __ret;
-#if !defined(__PIC__) || !defined(BROKEN_EBX_ASM)
-	__asm__ __volatile__ (SYSCALL_INSNS : "=a"(__ret) : "a"(n), "b"(a1), "c"(a2), "d"(a3) : "memory");
-#else
-	__asm__ __volatile__ (SYSCALL_INSNS_34 : "=a"(__ret) : "a"(n), "D"(a1), "c"(a2), "d"(a3) : "memory");
-#endif
-	return __ret;
+    return CALL_SYSINFO(n, a1, a2, a3);
 }
 
 static inline long __syscall4(long n, long a1, long a2, long a3, long a4)
 {
-	unsigned long __ret;
-#if !defined(__PIC__) || !defined(BROKEN_EBX_ASM)
-	__asm__ __volatile__ (SYSCALL_INSNS : "=a"(__ret) : "a"(n), "b"(a1), "c"(a2), "d"(a3), "S"(a4) : "memory");
-#else
-	__asm__ __volatile__ (SYSCALL_INSNS_34 : "=a"(__ret) : "a"(n), "D"(a1), "c"(a2), "d"(a3), "S"(a4) : "memory");
-#endif
-	return __ret;
+    return CALL_SYSINFO(n, a1, a2, a3, a4);
 }
 
 static inline long __syscall5(long n, long a1, long a2, long a3, long a4, long a5)
 {
-	unsigned long __ret;
-#if !defined(__PIC__) || !defined(BROKEN_EBX_ASM)
-	__asm__ __volatile__ (SYSCALL_INSNS
-		: "=a"(__ret) : "a"(n), "b"(a1), "c"(a2), "d"(a3), "S"(a4), "D"(a5) : "memory");
-#else
-	__asm__ __volatile__ ("pushl %2 ; push %%ebx ; mov 4(%%esp),%%ebx ; " SYSCALL_INSNS " ; pop %%ebx ; add $4,%%esp"
-		: "=a"(__ret) : "a"(n), "g"(a1), "c"(a2), "d"(a3), "S"(a4), "D"(a5) : "memory");
-#endif
-	return __ret;
+    return CALL_SYSINFO(n, a1, a2, a3, a4, a5);
 }
 
 static inline long __syscall6(long n, long a1, long a2, long a3, long a4, long a5, long a6)
 {
-	unsigned long __ret;
-#if !defined(__PIC__) || !defined(BROKEN_EBX_ASM)
-	__asm__ __volatile__ ("pushl %7 ; push %%ebp ; mov 4(%%esp),%%ebp ; " SYSCALL_INSNS " ; pop %%ebp ; add $4,%%esp"
-		: "=a"(__ret) : "a"(n), "b"(a1), "c"(a2), "d"(a3), "S"(a4), "D"(a5), "g"(a6) : "memory");
-#else
-	unsigned long a1a6[2] = { a1, a6 };
-	__asm__ __volatile__ ("pushl %1 ; push %%ebx ; push %%ebp ; mov 8(%%esp),%%ebx ; mov 4(%%ebx),%%ebp ; mov (%%ebx),%%ebx ; " SYSCALL_INSNS " ; pop %%ebp ; pop %%ebx ; add $4,%%esp"
-		: "=a"(__ret) : "g"(&a1a6), "a"(n), "c"(a2), "d"(a3), "S"(a4), "D"(a5) : "memory");
-#endif
-	return __ret;
+    return CALL_SYSINFO(n, a1, a2, a3, a4, a5, a6);
 }
-
-#define VDSO_USEFUL
-#define VDSO_CGT32_SYM "__vdso_clock_gettime"
-#define VDSO_CGT32_VER "LINUX_2.6"
-#define VDSO_CGT_SYM "__vdso_clock_gettime64"
-#define VDSO_CGT_VER "LINUX_2.6"
diff --git a/arch/x86_64/syscall_arch.h b/arch/x86_64/syscall_arch.h
index 92d5c1792..eb2133040 100644
--- a/arch/x86_64/syscall_arch.h
+++ b/arch/x86_64/syscall_arch.h
@@ -1,70 +1,41 @@
 #define __SYSCALL_LL_E(x) (x)
 #define __SYSCALL_LL_O(x) (x)
 
-static __inline long __syscall0(long n)
+#include <libc.h>
+
+#define CALL_SYSINFO(n, ...) (__sysinfo ? ((long(*)(long,...))__sysinfo)(n, ##__VA_ARGS__) : -1)
+
+static inline long __syscall0(long n)
 {
-	unsigned long ret;
-	__asm__ __volatile__ ("syscall" : "=a"(ret) : "a"(n) : "rcx", "r11", "memory");
-	return ret;
+    return CALL_SYSINFO(n);
 }
 
-static __inline long __syscall1(long n, long a1)
+static inline long __syscall1(long n, long a1)
 {
-	unsigned long ret;
-	__asm__ __volatile__ ("syscall" : "=a"(ret) : "a"(n), "D"(a1) : "rcx", "r11", "memory");
-	return ret;
+    return CALL_SYSINFO(n, a1);
 }
 
-static __inline long __syscall2(long n, long a1, long a2)
+static inline long __syscall2(long n, long a1, long a2)
 {
-	unsigned long ret;
-	__asm__ __volatile__ ("syscall" : "=a"(ret) : "a"(n), "D"(a1), "S"(a2)
-						  : "rcx", "r11", "memory");
-	return ret;
+    return CALL_SYSINFO(n, a1, a2);
 }
 
-static __inline long __syscall3(long n, long a1, long a2, long a3)
+static inline long __syscall3(long n, long a1, long a2, long a3)
 {
-	unsigned long ret;
-	__asm__ __volatile__ ("syscall" : "=a"(ret) : "a"(n), "D"(a1), "S"(a2),
-						  "d"(a3) : "rcx", "r11", "memory");
-	return ret;
+    return CALL_SYSINFO(n, a1, a2, a3);
 }
 
-static __inline long __syscall4(long n, long a1, long a2, long a3, long a4)
+static inline long __syscall4(long n, long a1, long a2, long a3, long a4)
 {
-	unsigned long ret;
-	register long r10 __asm__("r10") = a4;
-	__asm__ __volatile__ ("syscall" : "=a"(ret) : "a"(n), "D"(a1), "S"(a2),
-						  "d"(a3), "r"(r10): "rcx", "r11", "memory");
-	return ret;
+    return CALL_SYSINFO(n, a1, a2, a3, a4);
 }
 
-static __inline long __syscall5(long n, long a1, long a2, long a3, long a4, long a5)
+static inline long __syscall5(long n, long a1, long a2, long a3, long a4, long a5)
 {
-	unsigned long ret;
-	register long r10 __asm__("r10") = a4;
-	register long r8 __asm__("r8") = a5;
-	__asm__ __volatile__ ("syscall" : "=a"(ret) : "a"(n), "D"(a1), "S"(a2),
-						  "d"(a3), "r"(r10), "r"(r8) : "rcx", "r11", "memory");
-	return ret;
+    return CALL_SYSINFO(n, a1, a2, a3, a4, a5);
 }
 
-static __inline long __syscall6(long n, long a1, long a2, long a3, long a4, long a5, long a6)
+static inline long __syscall6(long n, long a1, long a2, long a3, long a4, long a5, long a6)
 {
-	unsigned long ret;
-	register long r10 __asm__("r10") = a4;
-	register long r8 __asm__("r8") = a5;
-	register long r9 __asm__("r9") = a6;
-	__asm__ __volatile__ ("syscall" : "=a"(ret) : "a"(n), "D"(a1), "S"(a2),
-						  "d"(a3), "r"(r10), "r"(r8), "r"(r9) : "rcx", "r11", "memory");
-	return ret;
+    return CALL_SYSINFO(n, a1, a2, a3, a4, a5, a6);
 }
-
-#define VDSO_USEFUL
-#define VDSO_CGT_SYM "__vdso_clock_gettime"
-#define VDSO_CGT_VER "LINUX_2.6"
-#define VDSO_GETCPU_SYM "__vdso_getcpu"
-#define VDSO_GETCPU_VER "LINUX_2.6"
-
-#define IPC_64 0

@wom-bat
Copy link
Member

wom-bat commented Dec 5, 2023

https://git.musl-libc.org/cgit/musl/commit/?id=d8f2efa708a027132d443f45a8c98a0c7c1b2d77 is needed sooner, as without it compilation with current GCC fails.

@Indanz
Copy link

Indanz commented Dec 11, 2023

Any reason why a standard, unmodified libc like newlib isn't used, instead of taking on the burden of keeping a fork up-to-date?

That's what we used at my previous work for the applications we loaded (we used the root server as a sort of bootloader, so we could update and reload the application without rebooting the machine).

As far as I know the only incompatibility is which register is being used for TLS, but here seL4 picked a non-standard way of doing things too.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

When branches are created from issues, their pull requests are automatically linked.

4 participants