Modify stdio to support Trusty kernel
This commit modifies musl's stdio to support the kernel by
1. replacing the syscall in __stdio_write with a call to writev
2. removing support for the floating-point code in stdio
3. replacing __pthread_self with current_thread_libc_state
4. redefining macros that don't apply to stdout/stderr (e.g. FLOCK)
to avoid needing to compile/stub out pthread sources
Bug: 230134581
Change-Id: I985496b6fc62176ff33ad5ebb90c694cd5309977
diff --git a/arch/aarch64/pthread_arch.h b/arch/aarch64/pthread_arch.h
index e64b126..14e3f85 100644
--- a/arch/aarch64/pthread_arch.h
+++ b/arch/aarch64/pthread_arch.h
@@ -1,9 +1,11 @@
+#if defined(TRUSTY_USERSPACE)
static inline struct pthread *__pthread_self()
{
char *self;
__asm__ ("mrs %0,tpidr_el0" : "=r"(self));
return (void*)(self - sizeof(struct pthread));
}
+#endif
#define TLS_ABOVE_TP
#define GAP_ABOVE_TP 16
diff --git a/arch/arm/pthread_arch.h b/arch/arm/pthread_arch.h
index e689ea2..951a416 100644
--- a/arch/arm/pthread_arch.h
+++ b/arch/arm/pthread_arch.h
@@ -1,3 +1,4 @@
+#if defined(TRUSTY_USERSPACE)
#if ((__ARM_ARCH_6K__ || __ARM_ARCH_6KZ__ || __ARM_ARCH_6ZK__) && !__thumb__) \
|| __ARM_ARCH_7A__ || __ARM_ARCH_7R__ || __ARM_ARCH >= 7
@@ -25,6 +26,7 @@
}
#endif
+#endif
#define TLS_ABOVE_TP
#define GAP_ABOVE_TP 8
diff --git a/arch/x86_64/pthread_arch.h b/arch/x86_64/pthread_arch.h
index 65e880c..8abc8fd 100644
--- a/arch/x86_64/pthread_arch.h
+++ b/arch/x86_64/pthread_arch.h
@@ -1,9 +1,11 @@
+#if defined(TRUSTY_USERSPACE)
static inline struct pthread *__pthread_self()
{
struct pthread *self;
__asm__ ("mov %%fs:0,%0" : "=r" (self) );
return self;
}
+#endif
#define TP_ADJ(p) (p)
diff --git a/src/internal/locale_impl.h b/src/internal/locale_impl.h
index 741a71c..142649f 100644
--- a/src/internal/locale_impl.h
+++ b/src/internal/locale_impl.h
@@ -4,7 +4,11 @@
#include <locale.h>
#include <stdlib.h>
#include "libc.h"
+#if defined(TRUSTY_USERSPACE)
#include "pthread_impl.h"
+#else
+#include <trusty/libc_state.h>
+#endif
#define LOCALE_NAME_MAX 23
@@ -35,9 +39,17 @@
#define C_LOCALE ((locale_t)&__c_locale)
#define UTF8_LOCALE ((locale_t)&__c_dot_utf8_locale)
+#if defined(TRUSTY_USERSPACE)
#define CURRENT_LOCALE (__pthread_self()->locale)
+#else
+#define CURRENT_LOCALE (current_thread_libc_state()->locale)
+#endif
+#if defined(TRUSTY_USERSPACE)
#define CURRENT_UTF8 (!!__pthread_self()->locale->cat[LC_CTYPE])
+#else
+#define CURRENT_UTF8 (!!C_LOCALE->cat[LC_CTYPE])
+#endif
#undef MB_CUR_MAX
#define MB_CUR_MAX (CURRENT_UTF8 ? 4 : 1)
diff --git a/src/internal/stdio_impl.h b/src/internal/stdio_impl.h
index b613c43..ecb1421 100644
--- a/src/internal/stdio_impl.h
+++ b/src/internal/stdio_impl.h
@@ -1,13 +1,24 @@
#ifndef _STDIO_IMPL_H
#define _STDIO_IMPL_H
+#include <assert.h>
#include <stdio.h>
#define UNGET 8
+#if defined(TRUSTY_USERSPACE)
#define FFINALLOCK(f) ((f)->lock>=0 ? __lockfile((f)) : 0)
#define FLOCK(f) int __need_unlock = ((f)->lock>=0 ? __lockfile((f)) : 0)
#define FUNLOCK(f) do { if (__need_unlock) __unlockfile((f)); } while (0)
+#else
+/* Trusty only supports the std streams which all have `lock = -1`, so these
+ * macros are unnecessary. Defining them as no-ops lets us avoid compiling
+ * __lockfile.c which makes use of __pthread_self which is not defined in the
+ * kernel. */
+#define FFINALLOCK(f) do { DEBUG_ASSERT((f)->lock == -1); } while (0)
+#define FLOCK(f) do { DEBUG_ASSERT((f)->lock == -1); } while (0)
+#define FUNLOCK(f) do { DEBUG_ASSERT((f)->lock == -1); } while (0)
+#endif
#define F_PERM 1
#define F_NORD 4
diff --git a/src/stdio/__stdio_write.c b/src/stdio/__stdio_write.c
index a02cc74..cb7034e 100644
--- a/src/stdio/__stdio_write.c
+++ b/src/stdio/__stdio_write.c
@@ -1,6 +1,10 @@
#include "stdio_impl.h"
#include <sys/uio.h>
-#include <trusty_syscalls.h>
+#if defined(TRUSTY_USERSPACE)
+#include <trusty_uio.h>
+#else
+#include <trusty/uio.h>
+#endif
size_t __stdio_write(FILE *f, const unsigned char *buf, size_t len)
{
@@ -13,7 +17,7 @@
int iovcnt = 2;
ssize_t cnt;
for (;;) {
- cnt = _trusty_writev(f->fd, iov, iovcnt);
+ cnt = trusty_writev(f->fd, iov, iovcnt);
if (cnt == rem) {
f->wend = f->buf + f->buf_size;
f->wpos = f->wbase = f->buf;
diff --git a/src/stdio/getc.h b/src/stdio/getc.h
index e24f990..27c4f3e 100644
--- a/src/stdio/getc.h
+++ b/src/stdio/getc.h
@@ -15,8 +15,12 @@
static inline int do_getc(FILE *f)
{
+#if defined(TRUSTY_USERSPACE)
int l = f->lock;
if (l < 0 || l && (l & ~MAYBE_WAITERS) == __pthread_self()->tid)
return getc_unlocked(f);
return locking_getc(f);
+#else
+ return getc_unlocked(f);
+#endif
}
diff --git a/src/stdio/putc.h b/src/stdio/putc.h
index 2014c4e..967e5d1 100644
--- a/src/stdio/putc.h
+++ b/src/stdio/putc.h
@@ -15,8 +15,12 @@
static inline int do_putc(int c, FILE *f)
{
+#if defined(TRUSTY_USERSPACE)
int l = f->lock;
if (l < 0 || l && (l & ~MAYBE_WAITERS) == __pthread_self()->tid)
return putc_unlocked(c, f);
return locking_putc(c, f);
+#else
+ return putc_unlocked(c, f);
+#endif
}
diff --git a/src/stdio/vfprintf.c b/src/stdio/vfprintf.c
index 03761eb..6f3054b 100644
--- a/src/stdio/vfprintf.c
+++ b/src/stdio/vfprintf.c
@@ -189,6 +189,7 @@
break; case UMAX: arg->i = va_arg(*ap, uintmax_t);
break; case PDIFF: arg->i = va_arg(*ap, ptrdiff_t);
break; case UIPTR: arg->i = (uintptr_t)va_arg(*ap, void *);
+#if !WITH_NO_FP
break; case DBL: arg->f = (stdio_float)va_arg(*ap, double);
#if STDIO_FLOAT == 128
break; case LDBL: arg->f = va_arg(*ap, long double);
@@ -196,6 +197,9 @@
/* Zero out to avoid software conversion. */
break; case LDBL: va_arg(*ap, long double); arg->f = 0;
#endif
+#else
+ break; default: panic("Floating point code is not supported\n");
+#endif // !WITH_NO_FP
}
}
@@ -259,6 +263,7 @@
typedef char compiler_defines_long_double_incorrectly[9-(int)sizeof(long double)];
#endif
+#if !WITH_NO_FP
/* TRUSTY - noinline to save stack space when floats are not printed. */
__attribute__((__noinline__))
static int fmt_fp(FILE *f, stdio_float y, int w, int p, int fl, int t)
@@ -501,6 +506,7 @@
return MAX(w, pl+l);
}
+#endif
static int getint(char **s) {
int i;
@@ -802,7 +808,11 @@
break;
#else
if (xp && p<0) goto overflow;
+#if !WITH_NO_FP
l = fmt_fp(f, arg.f, w, p, fl, t);
+#else
+ panic("Floating point code is not supported\n");
+#endif
if (l<0) goto overflow;
continue;
#endif
diff --git a/src/stdio/vfscanf.c b/src/stdio/vfscanf.c
index 9e030fc..1af3bf8 100644
--- a/src/stdio/vfscanf.c
+++ b/src/stdio/vfscanf.c
@@ -68,7 +68,9 @@
int invert;
int matches=0;
unsigned long long x;
+#if !WITH_NO_FP
long double y;
+#endif
off_t pos = 0;
unsigned char scanset[257];
size_t i, k;
@@ -299,6 +301,7 @@
case 'e': case 'E':
case 'f': case 'F':
case 'g': case 'G':
+#if !WITH_NO_FP
y = __floatscan(f, size, 0);
if (!shcnt(f)) goto match_fail;
if (dest) switch (size) {
@@ -312,6 +315,9 @@
*(long double *)dest = y;
break;
}
+#else
+ panic("Floating point code is not supported\n");
+#endif
break;
}