From d62085e5c5eb47cc2442899b125c799cb90e6d7b Mon Sep 17 00:00:00 2001 From: Samuel Thibault Date: Fri, 6 Apr 2012 21:17:05 +0200 Subject: Do not take address of va_list variable This breaks on x86_64, where it is an array and thus gets bogus results. * ddb/db_output.c (db_printf, kdbprintf): Pass copy of va_list variable instead of its address. * kern/debug.c (panic, log): Likewise. * kern/printf.c (vprintf, iprintf, sprintf, vsnprintf): Likewise. (_doprnt): Take va_list instead of va_list *, fix usage and comment accordingly. * kern/printf.h (_doprnt): Take va_list instead of va_list *. --- ddb/db_output.c | 4 ++-- kern/debug.c | 4 ++-- kern/printf.c | 29 ++++++++++++++++------------- kern/printf.h | 2 +- 4 files changed, 21 insertions(+), 18 deletions(-) diff --git a/ddb/db_output.c b/ddb/db_output.c index 57d6856..3ea2caa 100644 --- a/ddb/db_output.c +++ b/ddb/db_output.c @@ -213,7 +213,7 @@ db_printf(const char *fmt, ...) db_printf_enter(); /* optional multiP serialization */ #endif va_start(listp, fmt); - _doprnt(fmt, &listp, db_id_putc, db_radix, 0); + _doprnt(fmt, listp, db_id_putc, db_radix, 0); va_end(listp); } @@ -225,7 +225,7 @@ kdbprintf(const char *fmt, ...) { va_list listp; va_start(listp, fmt); - _doprnt(fmt, &listp, db_id_putc, db_radix, 0); + _doprnt(fmt, listp, db_id_putc, db_radix, 0); va_end(listp); } diff --git a/kern/debug.c b/kern/debug.c index 65c43fb..09c8ff4 100644 --- a/kern/debug.c +++ b/kern/debug.c @@ -168,7 +168,7 @@ panic(const char *s, ...) #endif printf(": "); va_start(listp, s); - _doprnt(s, &listp, do_cnputc, 0, 0); + _doprnt(s, listp, do_cnputc, 0, 0); va_end(listp); printf("\n"); @@ -203,7 +203,7 @@ log(int level, const char *fmt, ...) level++; #endif va_start(listp, fmt); - _doprnt(fmt, &listp, do_cnputc, 0, 0); + _doprnt(fmt, listp, do_cnputc, 0, 0); va_end(listp); } diff --git a/kern/printf.c b/kern/printf.c index 658493c..a3a771d 100644 --- a/kern/printf.c +++ b/kern/printf.c @@ -39,7 +39,10 @@ * FILE *fd; * char *format; * { + * va_list listp; + * va_start(listp, fmt); * _doprnt(format, &args, fd); + * va_end(listp); * } * * would suffice. (This example does not handle the fprintf's "return @@ -165,7 +168,7 @@ void printf_init(void) void _doprnt( register const char *fmt, - va_list *argp, + va_list argp, /* character output routine */ void (*putc)( char, vm_offset_t), int radix, /* default radix - for '%r' */ @@ -248,7 +251,7 @@ void _doprnt( } } else if (c == '*') { - length = va_arg(*argp, int); + length = va_arg(argp, int); c = *++fmt; if (length < 0) { ladjust = !ladjust; @@ -266,7 +269,7 @@ void _doprnt( } } else if (c == '*') { - prec = va_arg(*argp, int); + prec = va_arg(argp, int); c = *++fmt; } } @@ -284,8 +287,8 @@ void _doprnt( boolean_t any; register int i; - u = va_arg(*argp, unsigned long); - p = va_arg(*argp, char *); + u = va_arg(argp, unsigned long); + p = va_arg(argp, char *); base = *p++; printnum(u, base, putc, putc_arg); @@ -333,7 +336,7 @@ void _doprnt( } case 'c': - c = va_arg(*argp, int); + c = va_arg(argp, int); (*putc)(c, putc_arg); break; @@ -345,7 +348,7 @@ void _doprnt( if (prec == -1) prec = 0x7fffffff; /* MAXINT */ - p = va_arg(*argp, char *); + p = va_arg(argp, char *); if (p == (char *)0) p = ""; @@ -428,7 +431,7 @@ void _doprnt( goto print_unsigned; print_signed: - n = va_arg(*argp, long); + n = va_arg(argp, long); if (n >= 0) { u = n; sign_char = plus_sign; @@ -440,7 +443,7 @@ void _doprnt( goto print_num; print_unsigned: - u = va_arg(*argp, unsigned long); + u = va_arg(argp, unsigned long); goto print_num; print_num: @@ -514,7 +517,7 @@ void _doprnt( int vprintf(const char *fmt, va_list listp) { - _doprnt(fmt, &listp, (void (*)( char, vm_offset_t)) cnputc, 16, 0); + _doprnt(fmt, listp, (void (*)( char, vm_offset_t)) cnputc, 16, 0); return 0; } @@ -550,7 +553,7 @@ void iprintf(const char *fmt, ...) } } va_start(listp, fmt); - _doprnt(fmt, &listp, (void (*)( char, vm_offset_t)) cnputc, 16, 0); + _doprnt(fmt, listp, (void (*)( char, vm_offset_t)) cnputc, 16, 0); va_end(listp); } @@ -577,7 +580,7 @@ sprintf(char *buf, const char *fmt, ...) char *start = buf; va_start(listp, fmt); - _doprnt(fmt, &listp, sputc, 16, (vm_offset_t)&buf); + _doprnt(fmt, listp, sputc, 16, (vm_offset_t)&buf); va_end(listp); *buf = 0; @@ -606,7 +609,7 @@ vsnprintf(char *buf, size_t size, const char *fmt, va_list args) struct vsnprintf_cookie cookie = { .buf = buf, .index = 0, .max_len = size }; - _doprnt (fmt, &args, snputc, 16, (vm_offset_t)&cookie); + _doprnt (fmt, args, snputc, 16, (vm_offset_t)&cookie); cookie.buf[cookie.index] = '\0'; return cookie.index; diff --git a/kern/printf.h b/kern/printf.h index fcf2b3b..8b4e760 100644 --- a/kern/printf.h +++ b/kern/printf.h @@ -30,7 +30,7 @@ extern void printf_init (void); extern void _doprnt (const char *fmt, - va_list *argp, + va_list argp, void (*putc)(char, vm_offset_t), int radix, vm_offset_t putc_arg); -- cgit v1.2.3