From d62085e5c5eb47cc2442899b125c799cb90e6d7b Mon Sep 17 00:00:00 2001
From: Samuel Thibault <samuel.thibault@ens-lyon.org>
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 57d6856d..3ea2caac 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 65c43fba..09c8ff48 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 658493cc..a3a771d0 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 fcf2b3b0..8b4e7606 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