Index: sys/compat/linuxkpi/common/include/linux/kernel.h =================================================================== --- sys/compat/linuxkpi/common/include/linux/kernel.h +++ sys/compat/linuxkpi/common/include/linux/kernel.h @@ -138,11 +138,6 @@ extern void linux_dump_stack(void); #define dump_stack() linux_dump_stack() -struct va_format { - const char *fmt; - va_list *va; -}; - static inline int vscnprintf(char *buf, size_t size, const char *fmt, va_list args) { Index: sys/kern/subr_prf.c =================================================================== --- sys/kern/subr_prf.c +++ sys/kern/subr_prf.c @@ -665,6 +665,7 @@ char nbuf[MAXNBUF]; char *d; const char *p, *percent, *q; + struct va_format *vaf; u_char *up; int ch, n, sign; uintmax_t num; @@ -819,11 +820,35 @@ base = 8; goto handle_nosign; case 'p': - base = 16; - sharpflag = (width == 0); - sign = 0; - num = (uintptr_t)va_arg(ap, void *); - goto number; + switch (*fmt) { + case 'V': + fmt++; + + vaf = va_arg(ap, struct va_format *); + if (vaf == NULL) { + p = "(null)"; + n = strlen(p); + while (n--) + PCHAR(*p++); + break; + } + + if (func) { + retval += kvprintf(vaf->fmt, func, arg, radix, + *vaf->va); + } else { + retval += kvprintf(vaf->fmt, NULL, d, radix, + *vaf->va); + } + break; + default: + base = 16; + sharpflag = (width == 0); + sign = 0; + num = (uintptr_t)va_arg(ap, void *); + goto number; + } + break; case 'q': qflag = 1; goto reswitch; Index: sys/sys/systm.h =================================================================== --- sys/sys/systm.h +++ sys/sys/systm.h @@ -251,6 +251,11 @@ #define HD_OMIT_HEX (1 << 17) #define HD_OMIT_CHARS (1 << 18) +struct va_format { + const char *fmt; + __va_list *va; +}; + #define ovbcopy(f, t, l) bcopy((f), (t), (l)) void explicit_bzero(void * _Nonnull, size_t);