Make glibc's printf with a vcore-ctx aware (XCC)
authorBarret Rhoden <brho@cs.berkeley.edu>
Mon, 14 Dec 2015 20:04:47 +0000 (15:04 -0500)
committerBarret Rhoden <brho@cs.berkeley.edu>
Wed, 16 Dec 2015 23:23:10 +0000 (18:23 -0500)
This is a follow-up to commit 36acdc59f895 ("Override glibc's printf for
vcore context").

Using a #define for printf turned into a mess.  This approach accomplishes
the same goals (printf can be safely called from vcore context), but
without preprocessor magic.

Rebuild glibc.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/Versions
tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/parlib-compat.c
tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/printf.c [new file with mode: 0644]
user/parlib/include/stdio.h

index e991269..d2b3cc3 100644 (file)
@@ -56,7 +56,9 @@ libc {
     eventfd_write;
 
     # Weak symbols in parlib-compat.c
+    __vcore_context;
     akaros_printf;
+    akaros_vprintf;
     print_user_context;
     _assert_failed;
   }
index 881e6e2..b84efa7 100644 (file)
@@ -6,13 +6,18 @@
 #include <libc-symbols.h>
 #include <parlib/stdio.h>
 #include <parlib/assert.h>
+#include <stdbool.h>
 
-/* Here we define functions that are really defined in parlib, but we need
- * them in libc in order to link it. We weak alias them here so that the
- * parlib definitions will override them later. Unfortunately, this trick
- * only works so long as we leave parlib as a static library. If we ever
- * decide to make parlib a .so, then we will have to revisit this and use
- * function pointers at runtime or something similar. */
+/* Here we define functions and variables that are really defined in parlib, but
+ * we need them in libc in order to link it. We weak alias them here so that the
+ * parlib definitions will override them later.
+ *
+ * Unfortunately, this trick only works so long as we leave parlib as a static
+ * library. If we ever decide to make parlib a .so, then we will have to revisit
+ * this and use function pointers at runtime or something similar. */
+
+__thread bool __weak_vcore_context = FALSE;
+weak_alias(__weak_vcore_context, __vcore_context);
 
 int __akaros_printf(const char *format, ...)
 {
@@ -21,6 +26,13 @@ int __akaros_printf(const char *format, ...)
 }
 weak_alias(__akaros_printf, akaros_printf)
 
+int __akaros_vprintf(const char *fmt, va_list ap)
+{
+       assert(0);
+       return -1;
+}
+weak_alias(__akaros_vprintf, akaros_vprintf)
+
 void __print_user_context(struct user_context *ctx)
 {
        assert(0);
diff --git a/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/printf.c b/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/printf.c
new file mode 100644 (file)
index 0000000..20598c6
--- /dev/null
@@ -0,0 +1,46 @@
+/* Copyright (C) 1991-2014 Free Software Foundation, Inc.
+ * This file is part of the GNU C Library.
+ *
+ * The GNU C Library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+
+ * The GNU C Library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the GNU C Library; if not, see
+ * <http://www.gnu.org/licenses/>.  */
+
+#include <libioP.h>
+#include <stdarg.h>
+#include <stdio.h>
+
+#include <parlib/stdio.h>
+#include <parlib/vcore.h>
+
+#undef printf
+
+/* Write formatted output to stdout from the format string FORMAT.  */
+/* VARARGS1 */
+int __printf(const char *format, ...)
+{
+       va_list ap;
+       int ret;
+
+       va_start(ap, format);
+       if (in_vcore_context())
+               ret = akaros_vprintf(format, ap);
+       else
+               ret = vfprintf(stdout, format, ap);
+       va_end(ap);
+       return ret;
+}
+
+#undef _IO_printf
+ldbl_strong_alias(__printf, printf);
+/* This is for libg++.  */
+ldbl_strong_alias(__printf, _IO_printf);
index e752bc2..0c5ddab 100644 (file)
@@ -18,6 +18,10 @@ __BEGIN_DECLS
 void akaros_vprintfmt(void (*putch)(int, void**), void **putdat,
                       const char *fmt, va_list);
 int akaros_vprintf(const char *fmt, va_list);
+/* This is the same as our sysdep for glibc's printf.  We use this to print in
+ * a few places in glibc that can't link directly against printf.  (the
+ * 'multiple libcs' problem). */
+int akaros_printf(const char *format, ...);
 
 #ifdef PRINTD_DEBUG
 #define printd(args...) printf(args)
@@ -25,10 +29,4 @@ int akaros_vprintf(const char *fmt, va_list);
 #define printd(args...) {}
 #endif
 
-/* Override glibc's printf; ours will be safe from VC context, and uses glibc's
- * otherwise. */
-int akaros_printf(const char *format, ...);
-#undef printf
-#define printf(args...) akaros_printf(args)
-
 __END_DECLS