Modify glibc's printf for use from VC ctx (XCC)
authorBarret Rhoden <brho@cs.berkeley.edu>
Mon, 11 Apr 2016 16:27:05 +0000 (12:27 -0400)
committerBarret Rhoden <brho@cs.berkeley.edu>
Fri, 15 Apr 2016 14:29:13 +0000 (10:29 -0400)
The existing hack for calling to vcore context doesn't work for snprintf.
Glibc uses the same backend for printing to files as well as buffers, which
makes sense since you only want to do format string handling once.  Our
hack only worked for files; if you did an snprintf from vcore context,
you'd fail (write to fd -1, incidentally).

Instead of hacking glibc to use our printf, we'll just hack out the major
stack gobblers from glibc's vprintf.  We'll see if this works or not.

As a side effect, we don't need our parlib version of printfmt.  I'm glad
to see it go, since it wasn't compatible with glibc's - including printf
format specifiers we registered with glibc.  You could have a format string
that was processed differently in vcore ctx than in uthread ctx, which
would be confusing.

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/vfprintf.c
user/parlib/debug.c
user/parlib/debugfmt.c [deleted file]
user/parlib/include/parlib/stdio.h

index ac4864f..8f96d02 100644 (file)
@@ -63,7 +63,6 @@ libc {
     __vcoreid;
     __vcore_context;
     akaros_printf;
-    akaros_vfprintf;
     print_user_context;
     _assert_failed;
   }
index 4d5c1ab..c6fd1b5 100644 (file)
@@ -31,13 +31,6 @@ int __akaros_printf(const char *format, ...)
 }
 weak_alias(__akaros_printf, akaros_printf)
 
-int __akaros_vfprintf(FILE *stream, const char *fmt, va_list ap)
-{
-       assert(0);
-       return -1;
-}
-weak_alias(__akaros_vfprintf, akaros_vfprintf)
-
 void __print_user_context(struct user_context *ctx)
 {
        assert(0);
index 848c80d..6e20aba 100644 (file)
@@ -30,9 +30,7 @@
 #include <locale/localeinfo.h>
 #include <stdio.h>
 
-/* AKAROS: added a callout to our vprintf for vcore context */
-#include <parlib/stdio.h>
-#include <parlib/vcore.h>
+/* Modified for AKAROS, uses malloc in place of large stack allocations */
 
 /* This code is shared between the standard stdio implementation found
    in GNU C library and the libio implementation originally found in
@@ -224,10 +222,6 @@ static CHAR_T *group_number (CHAR_T *, CHAR_T *, const char *, const char *)
 int
 vfprintf (FILE *s, const CHAR_T *format, va_list ap)
 {
-       /* AKAROS */
-       if (in_vcore_context())
-               return akaros_vfprintf(s, format, ap);
-
   /* The character used as thousands separator.  */
 #ifdef COMPILE_WPRINTF
   wchar_t thousands_sep = L'\0';
@@ -251,7 +245,10 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap)
   const UCHAR_T *end_of_spec;
 
   /* Buffer intermediate results.  */
-  CHAR_T work_buffer[1000];
+  /* AKAROS malloc work_buf */
+  //CHAR_T work_buffer[1000];
+  CHAR_T *work_buffer = malloc(1000);
+
   CHAR_T *workstart = NULL;
   CHAR_T *workend;
 
@@ -2061,6 +2058,8 @@ all_done:
   _IO_funlockfile (s);
   _IO_cleanup_region_end (0);
 
+  /* AKAROS */
+  free(work_buffer);
   return done;
 }
 \f
@@ -2284,7 +2283,10 @@ internal_function
 buffered_vfprintf (_IO_FILE *s, const CHAR_T *format,
                   _IO_va_list args)
 {
-  CHAR_T buf[_IO_BUFSIZ];
+       /* AKAROS: malloc the buf.  */
+  //CHAR_T buf[_IO_BUFSIZ];
+  CHAR_T *buf = malloc(_IO_BUFSIZ);
+
   struct helper_file helper;
   _IO_FILE *hp = (_IO_FILE *) &helper._f;
   int result, to_flush;
@@ -2346,6 +2348,7 @@ buffered_vfprintf (_IO_FILE *s, const CHAR_T *format,
   _IO_funlockfile (s);
   __libc_cleanup_region_end (0);
 
+  free(buf); /* AKAROS */
   return result;
 }
 
index c2a6655..b8c3d8f 100644 (file)
@@ -1,54 +1,9 @@
-// Implementation of cprintf console output for user processes,
-// based on printfmt() and the write() system call.
-//
-// cprintf is a debugging statement, not a generic output statement.
-// It is very important that it always go to the console, especially when
-// debugging file descriptor code!
-
 #include <parlib/common.h>
 #include <parlib/parlib.h>
 #include <stdio.h>
 #include <unistd.h>
 #include <parlib/spinlock.h>
 
-// Collect up to BUF_SIZE characters into a buffer
-// and perform ONE system call to print all of them,
-// in order to make the lines output to the console atomic
-// and prevent interrupts from causing context switches
-// in the middle of a console output line and such.
-#define BUF_SIZE 256
-typedef struct debugbuf {
-       size_t  idx;    // current buffer index
-       size_t  cnt;    // total bytes printed so far
-       uint8_t buf[BUF_SIZE];
-       int     stream_fd;
-} debugbuf_t;
-
-
-static void putch(int ch, debugbuf_t **b)
-{
-       (*b)->buf[(*b)->idx++] = ch;
-       if ((*b)->idx == BUF_SIZE) {
-               write((*b)->stream_fd, (*b)->buf, (*b)->idx);
-               (*b)->idx = 0;
-       }
-       (*b)->cnt++;
-}
-
-int akaros_vfprintf(FILE *stream, const char *fmt, va_list ap)
-{
-       debugbuf_t b;
-       debugbuf_t *bp = &b;
-
-       b.idx = 0;
-       b.cnt = 0;
-       b.stream_fd = fileno(stream);
-       akaros_vprintfmt((void*)putch, (void*)&bp, fmt, ap);
-       write(b.stream_fd, b.buf, b.idx);
-
-       return b.cnt;
-}
-
 int akaros_printf(const char *format, ...)
 {
        va_list ap;
diff --git a/user/parlib/debugfmt.c b/user/parlib/debugfmt.c
deleted file mode 100644 (file)
index 1392b68..0000000
+++ /dev/null
@@ -1,196 +0,0 @@
-#include <parlib/common.h>
-#include <ros/errno.h>
-#include <string.h>
-#include <parlib/ros_debug.h>
-
-/*
- * Print a number (base <= 16) in reverse order,
- * using specified putch function and associated pointer putdat.
- */
-static void printnum(void (*putch)(int, void**), void **putdat,
-                        unsigned long long num, unsigned base, int width, int padc)
-{
-       // first recursively print all preceding (more significant) digits
-       if (num >= base) {
-               printnum(putch, putdat, num / base, base, width - 1, padc);
-       } else {
-               // print any needed pad characters before first digit
-               while (--width > 0)
-                       putch(padc, putdat);
-       }
-
-       // then print this (the least significant) digit
-       putch("0123456789abcdef"[num % base], putdat);
-}
-
-// Main function to format and print a string.
-void akaros_vprintfmt(void (*putch)(int, void**), void **putdat,
-                      const char *fmt, va_list ap)
-{
-       register const char *p;
-       const char *last_fmt;
-       register int ch, err;
-       unsigned long long num;
-       int base, lflag, width, precision, altflag;
-       char padc;
-
-       while (1) {
-               while ((ch = *(unsigned char *) fmt) != '%') {
-                       if (ch == '\0')
-                               return;
-                       fmt++;
-                       putch(ch, putdat);
-               }
-               fmt++;
-
-               // Process a %-escape sequence
-               last_fmt = fmt;
-               padc = ' ';
-               width = -1;
-               precision = -1;
-               lflag = 0;
-               altflag = 0;
-       reswitch:
-               switch (ch = *(unsigned char *) fmt++) {
-
-               // flag to pad on the right
-               case '-':
-                       padc = '-';
-                       goto reswitch;
-                       
-               // flag to pad with 0's instead of spaces
-               case '0':
-                       padc = '0';
-                       goto reswitch;
-
-               // width field
-               case '1':
-               case '2':
-               case '3':
-               case '4':
-               case '5':
-               case '6':
-               case '7':
-               case '8':
-               case '9':
-                       for (precision = 0; ; ++fmt) {
-                               precision = precision * 10 + ch - '0';
-                               ch = *fmt;
-                               if (ch < '0' || ch > '9')
-                                       break;
-                       }
-                       goto process_precision;
-
-               case '*':
-                       precision = va_arg(ap, int);
-                       goto process_precision;
-
-               case '.':
-                       if (width < 0)
-                               width = 0;
-                       goto reswitch;
-
-               case '#':
-                       altflag = 1;
-                       goto reswitch;
-
-               process_precision:
-                       if (width < 0)
-                               width = precision, precision = -1;
-                       goto reswitch;
-
-               // long flag (doubled for long long)
-               case 'l':
-                       lflag++;
-                       goto reswitch;
-
-               // character
-               case 'c':
-                       putch(va_arg(ap, int), putdat);
-                       break;
-
-               // string
-/*
-               case 'r':
-                       p = current_errstr();
-                       /* oh, barf. Now we look like glibc. * /
-                       goto putstring;
-*/
-               case 's':
-                       if ((p = va_arg(ap, char *)) == NULL)
-                               p = "(null)";
-//putstring:
-                       if (width > 0 && padc != '-')
-                               for (width -= strnlen(p, precision); width > 0; width--)
-                                       putch(padc, putdat);
-                       for (; (ch = *p) != '\0' && (precision < 0 || --precision >= 0); width--) {
-                               if (altflag && (ch < ' ' || ch > '~'))
-                                       putch('?', putdat);
-                               else
-                                       putch(ch, putdat);
-                               // zra: make sure *p isn't '\0' before inc'ing
-                               p++;
-                       }
-                       for (; width > 0; width--)
-                               putch(' ', putdat);
-                       break;
-
-               case 'd': /* (signed) decimal */
-                       if (lflag >= 2)
-                               num = va_arg(ap, long long);
-                       else if (lflag)
-                               num = va_arg(ap, long);
-                       else
-                               num = va_arg(ap, int);
-                       if ((long long) num < 0) {
-                               putch('-', putdat);
-                               num = -(long long) num;
-                       }
-                       base = 10;
-                       goto number;
-
-               case 'u': /* unsigned decimal */
-               case 'o': /* (unsigned) octal */
-               case 'x': /* (unsigned) hexadecimal */
-                       if (lflag >= 2)
-                               num = va_arg(ap, unsigned long long);
-                       else if (lflag)
-                               num = va_arg(ap, unsigned long);
-                       else
-                               num = va_arg(ap, unsigned int);
-                       if (ch == 'u')
-                               base = 10;
-                       else if (ch == 'o')
-                               base = 8;
-                       else    /* x */
-                               base = 16;
-                       goto number;
-
-               // pointer
-               case 'p':
-                       putch('0', putdat);
-                       putch('x', putdat);
-                       num = (unsigned long long)
-                               (uintptr_t) va_arg(ap, void *);
-                       base = 16;
-                       goto number;
-
-               number:
-                       printnum(putch, putdat, num, base, width, padc);
-                       break;
-
-               // escaped '%' character
-               case '%':
-                       putch(ch, putdat);
-                       break;
-                       
-               // unrecognized escape sequence - just print it literally
-               default:
-                       putch('%', putdat);
-                       fmt = last_fmt;
-                       //for (fmt--; fmt[-1] != '%'; fmt--)
-                               /* do nothing */;
-                       break;
-               }
-       }
-}
index cddbee3..0166c00 100644 (file)
@@ -11,9 +11,6 @@
 
 __BEGIN_DECLS
 
-void akaros_vprintfmt(void (*putch)(int, void**), void **putdat,
-                      const char *fmt, va_list);
-int akaros_vfprintf(FILE *stream, const char *fmt, va_list);
 /* This is just a wrapper implementing 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). */