Subject: kern/3747: 64-bit support for kernel printf
To: None <gnats-bugs@gnats.netbsd.org>
From: Matthias Drochner <drochner@zelz26.zel.kfa-juelich.de>
List: netbsd-bugs
Date: 06/13/1997 21:08:44
>Number:         3747
>Category:       kern
>Synopsis:       no support for %qx format in kernel debug messages
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    kern-bug-people (Kernel Bug People)
>State:          open
>Class:          change-request
>Submitter-Id:   net
>Arrival-Date:   Fri Jun 13 12:20:03 1997
>Last-Modified:
>Originator:     Matthias Drochner
>Organization:
	KFA Juelich
>Release:        -current
>Environment:
	NetBSD-current/i386
System: NetBSD zelz26 1.2E NetBSD 1.2E (TULIP.DEBUG) #6: Thu Jun 12 21:35:10 MEST 1997 drochner@zelz26:/home/drochner/netbsd-970513-map64/sys/arch/i386/compile/TULIP.DEBUG i386


>Description:
	There is no support for the 64-bit formats in kprintf() and sprintf()
(sys/kern/subr_prf.c). Since off_t is a quad, this would be good to have.
>How-To-Repeat:
	(read code)
>Fix:
	The following patch implements %q{xdo} (but not %ll{xdo}) for both
mentioned funktions. Should be sufficient for kernel use.
It's completely stolen from printf(3). The flags->oflags rename seems
reasonable to me to avoid artificial differences.
Btw, the "default" clauses seem superflous to me.

Index: subr_prf.c
===================================================================
RCS file: /zelnfs/s/sources/netbsd/src/sys/kern/subr_prf.c,v
retrieving revision 1.1.1.3.2.1
diff -c -2 -r1.1.1.3.2.1 subr_prf.c
*** 1.1.1.3.2.1	1997/06/03 15:14:43
--- subr_prf.c	1997/06/10 13:22:49
***************
*** 82,86 ****
   * It's the length of a long in base 8, plus NULL.
   */
! #define KSNPRINTN_BUFSIZE	(sizeof(long) * NBBY / 3 + 2)
  
  struct	tty *constty;			/* pointer to console "window" tty */
--- 82,86 ----
   * It's the length of a long in base 8, plus NULL.
   */
! #define KSNPRINTN_BUFSIZE	(sizeof(quad_t) * NBBY / 3 + 2)
  
  struct	tty *constty;			/* pointer to console "window" tty */
***************
*** 89,93 ****
  
  static void putchar __P((int, int, struct tty *));
! static char *ksnprintn __P((u_long, int, int *, char *, size_t));
  void kprintf __P((const char *, int, struct tty *, va_list));
  
--- 89,93 ----
  
  static void putchar __P((int, int, struct tty *));
! static char *ksnprintn __P((u_quad_t, int, int *, char *, size_t));
  void kprintf __P((const char *, int, struct tty *, va_list));
  
***************
*** 407,414 ****
   * formats only.
   */
  void
! kprintf(fmt, flags, tp, ap)
  	register const char *fmt;
! 	int flags;
  	struct tty *tp;
  	va_list ap;
--- 407,424 ----
   * formats only.
   */
+ #define	LONGINT		0x010		/* long integer */
+ #define	QUADINT		0x020		/* quad integer */
+ #define	SARG() \
+ 	(flags&QUADINT ? va_arg(ap, quad_t) : \
+ 	    flags&LONGINT ? va_arg(ap, long) : \
+ 	    (long)va_arg(ap, int))
+ #define	UARG() \
+ 	(flags&QUADINT ? va_arg(ap, u_quad_t) : \
+ 	    flags&LONGINT ? va_arg(ap, u_long) : \
+ 	    (u_long)va_arg(ap, u_int))
  void
! kprintf(fmt, oflags, tp, ap)
  	register const char *fmt;
! 	int oflags;
  	struct tty *tp;
  	va_list ap;
***************
*** 416,421 ****
  	register char *p, *q;
  	register int ch, n;
! 	u_long ul;
! 	int base, lflag, tmp, width;
  	char padc, snbuf[KSNPRINTN_BUFSIZE];
  
--- 426,431 ----
  	register char *p, *q;
  	register int ch, n;
! 	u_quad_t ul;
! 	int base, flags, tmp, width;
  	char padc, snbuf[KSNPRINTN_BUFSIZE];
  
***************
*** 426,432 ****
  			if (ch == '\0')
  				return;
! 			putchar(ch, flags, tp);
  		}
! 		lflag = 0;
  reswitch:	switch (ch = *(const u_char *)fmt++) {
  		case '0':
--- 436,442 ----
  			if (ch == '\0')
  				return;
! 			putchar(ch, oflags, tp);
  		}
! 		flags = 0;
  reswitch:	switch (ch = *(const u_char *)fmt++) {
  		case '0':
***************
*** 444,448 ****
  			goto reswitch;
  		case 'l':
! 			lflag = 1;
  			goto reswitch;
  		case 'b':
--- 454,461 ----
  			goto reswitch;
  		case 'l':
! 			flags |= LONGINT;
! 			goto reswitch;
! 		case 'q':
! 			flags |= QUADINT;
  			goto reswitch;
  		case 'b':
***************
*** 451,455 ****
  			for (q = ksnprintn(ul, *p++, NULL, snbuf,
  			    sizeof(snbuf)); (ch = *q--) != 0;)
! 				putchar(ch, flags, tp);
  
  			if (!ul)
--- 464,468 ----
  			for (q = ksnprintn(ul, *p++, NULL, snbuf,
  			    sizeof(snbuf)); (ch = *q--) != 0;)
! 				putchar(ch, oflags, tp);
  
  			if (!ul)
***************
*** 458,464 ****
  			for (tmp = 0; (n = *p++) != 0;) {
  				if (ul & (1 << (n - 1))) {
! 					putchar(tmp ? ',' : '<', flags, tp);
  					for (; (n = *p) > ' '; ++p)
! 						putchar(n, flags, tp);
  					tmp = 1;
  				} else
--- 471,477 ----
  			for (tmp = 0; (n = *p++) != 0;) {
  				if (ul & (1 << (n - 1))) {
! 					putchar(tmp ? ',' : '<', oflags, tp);
  					for (; (n = *p) > ' '; ++p)
! 						putchar(n, oflags, tp);
  					tmp = 1;
  				} else
***************
*** 467,479 ****
  			}
  			if (tmp)
! 				putchar('>', flags, tp);
  			break;
  		case 'c':
! 			putchar(va_arg(ap, int), flags, tp);
  			break;
  #ifndef __powerpc__			/* XXX XXX XXX */
  		case ':':
  			p = va_arg(ap, char *);
! 			kprintf(p, flags, tp, va_arg(ap, va_list));
  			break;
  #endif /* __powerpc__ */		/* XXX XXX XXX */
--- 480,492 ----
  			}
  			if (tmp)
! 				putchar('>', oflags, tp);
  			break;
  		case 'c':
! 			putchar(va_arg(ap, int), oflags, tp);
  			break;
  #ifndef __powerpc__			/* XXX XXX XXX */
  		case ':':
  			p = va_arg(ap, char *);
! 			kprintf(p, oflags, tp, va_arg(ap, va_list));
  			break;
  #endif /* __powerpc__ */		/* XXX XXX XXX */
***************
*** 482,526 ****
  				p = "(null)";
  			while ((ch = *p++) != 0)
! 				putchar(ch, flags, tp);
  			break;
  		case 'd':
! 			ul = lflag ? va_arg(ap, long) : va_arg(ap, int);
! 			if ((long)ul < 0) {
! 				putchar('-', flags, tp);
! 				ul = -(long)ul;
  			}
  			base = 10;
  			goto number;
  		case 'o':
! 			ul = lflag ? va_arg(ap, u_long) : va_arg(ap, u_int);
  			base = 8;
  			goto number;
  		case 'u':
! 			ul = lflag ? va_arg(ap, u_long) : va_arg(ap, u_int);
  			base = 10;
  			goto number;
  		case 'p':
! 			putchar('0', flags, tp);
! 			putchar('x', flags, tp);
  			ul = (u_long)va_arg(ap, void *);
  			base = 16;
  			goto number;
  		case 'x':
! 			ul = lflag ? va_arg(ap, u_long) : va_arg(ap, u_int);
  			base = 16;
  number:			p = ksnprintn(ul, base, &tmp, snbuf, sizeof(snbuf));
  			if (width && (width -= tmp) > 0)
  				while (width--)
! 					putchar(padc, flags, tp);
  			while ((ch = *p--) != 0)
! 				putchar(ch, flags, tp);
  			break;
  		default:
! 			putchar('%', flags, tp);
! 			if (lflag)
! 				putchar('l', flags, tp);
  			/* FALLTHROUGH */
  		case '%':
! 			putchar(ch, flags, tp);
  		}
  	}
--- 495,538 ----
  				p = "(null)";
  			while ((ch = *p++) != 0)
! 				putchar(ch, oflags, tp);
  			break;
  		case 'd':
! 		        ul = SARG();
! 			if ((quad_t)ul < 0) {
! 				putchar('-', oflags, tp);
! 				ul = -ul;
  			}
  			base = 10;
  			goto number;
  		case 'o':
! 			ul = UARG();
  			base = 8;
  			goto number;
  		case 'u':
! 			ul = UARG();
  			base = 10;
  			goto number;
  		case 'p':
! 			putchar('0', oflags, tp);
! 			putchar('x', oflags, tp);
  			ul = (u_long)va_arg(ap, void *);
  			base = 16;
  			goto number;
  		case 'x':
! 			ul = UARG();
  			base = 16;
  number:			p = ksnprintn(ul, base, &tmp, snbuf, sizeof(snbuf));
  			if (width && (width -= tmp) > 0)
  				while (width--)
! 					putchar(padc, oflags, tp);
  			while ((ch = *p--) != 0)
! 				putchar(ch, oflags, tp);
  			break;
  		default:
! 			putchar('%', oflags, tp);
! 		        /* flags??? */
  			/* FALLTHROUGH */
  		case '%':
! 			putchar(ch, oflags, tp);
  		}
  	}
***************
*** 581,586 ****
  	register char *p, *bp;
  	register int ch, base;
! 	u_long ul;
! 	int lflag, tmp, width;
  	va_list ap;
  	char padc, snbuf[KSNPRINTN_BUFSIZE];
--- 593,598 ----
  	register char *p, *bp;
  	register int ch, base;
! 	u_quad_t ul;
! 	int flags, tmp, width;
  	va_list ap;
  	char padc, snbuf[KSNPRINTN_BUFSIZE];
***************
*** 594,598 ****
  				return ((bp - buf) - 1);
  
! 		lflag = 0;
  reswitch:	switch (ch = *(const u_char *)fmt++) {
  		case '0':
--- 606,610 ----
  				return ((bp - buf) - 1);
  
! 		flags = 0;
  reswitch:	switch (ch = *(const u_char *)fmt++) {
  		case '0':
***************
*** 609,613 ****
  			goto reswitch;
  		case 'l':
! 			lflag = 1;
  			goto reswitch;
  		/* case 'b': ... break; XXX */
--- 621,628 ----
  			goto reswitch;
  		case 'l':
! 			flags |= LONGINT;
! 			goto reswitch;
! 		case 'q':
! 			flags |= QUADINT;
  			goto reswitch;
  		/* case 'b': ... break; XXX */
***************
*** 623,644 ****
  			break;
  		case 'd':
! 			ul = lflag ? va_arg(ap, long) : va_arg(ap, int);
! 			if ((long)ul < 0) {
  				*bp++ = '-';
! 				ul = -(long)ul;
  			}
  			base = 10;
  			goto number;
- 			break;
  		case 'o':
! 			ul = lflag ? va_arg(ap, u_long) : va_arg(ap, u_int);
  			base = 8;
  			goto number;
- 			break;
  		case 'u':
! 			ul = lflag ? va_arg(ap, u_long) : va_arg(ap, u_int);
  			base = 10;
  			goto number;
- 			break;
  		case 'p':
  			*bp++ = '0';
--- 638,656 ----
  			break;
  		case 'd':
! 		        ul = SARG();
! 			if ((quad_t)ul < 0) {
  				*bp++ = '-';
! 				ul = -ul;
  			}
  			base = 10;
  			goto number;
  		case 'o':
! 			ul = UARG();
  			base = 8;
  			goto number;
  		case 'u':
! 			ul = UARG();
  			base = 10;
  			goto number;
  		case 'p':
  			*bp++ = '0';
***************
*** 648,652 ****
  			goto number;
  		case 'x':
! 			ul = lflag ? va_arg(ap, u_long) : va_arg(ap, u_int);
  			base = 16;
  number:			p = ksnprintn(ul, base, &tmp, snbuf, sizeof(snbuf));
--- 660,664 ----
  			goto number;
  		case 'x':
! 			ul = UARG();
  			base = 16;
  number:			p = ksnprintn(ul, base, &tmp, snbuf, sizeof(snbuf));
***************
*** 659,664 ****
  		default:
  			*bp++ = '%';
! 			if (lflag)
! 				*bp++ = 'l';
  			/* FALLTHROUGH */
  		case '%':
--- 671,675 ----
  		default:
  			*bp++ = '%';
! 		        /* flags??? */
  			/* FALLTHROUGH */
  		case '%':
***************
*** 676,680 ****
  static char *
  ksnprintn(ul, base, lenp, buf, buflen)
! 	register u_long ul;
  	register int base, *lenp;
  	char *buf;
--- 687,691 ----
  static char *
  ksnprintn(ul, base, lenp, buf, buflen)
! 	register u_quad_t ul;
  	register int base, *lenp;
  	char *buf;
>Audit-Trail:
>Unformatted: