2 * This file is part of the Palacios Virtual Machine Monitor developed
3 * by the V3VEE Project with funding from the United States National
4 * Science Foundation and the Department of Energy.
6 * The V3VEE Project is a joint project between Northwestern University
7 * and the University of New Mexico. You can find out more at
10 * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu>
11 * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
12 * All rights reserved.
14 * Author: Jack Lange <jarusl@cs.northwestern.edu>
16 * This is free software. You are permitted to use,
17 * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
25 * Copyright (c) 1986, 1988, 1991, 1993
26 * The Regents of the University of California. All rights reserved.
27 * (c) UNIX System Laboratories, Inc.
28 * All or some portions of this file are derived from material licensed
29 * to the University of California by American Telephone and Telegraph
30 * Co. or Unix System Laboratories, Inc. and are reproduced herein with
31 * the permission of UNIX System Laboratories, Inc.
33 * Redistribution and use in source and binary forms, with or without
34 * modification, are permitted provided that the following conditions
36 * 1. Redistributions of source code must retain the above copyright
37 * notice, this list of conditions and the following disclaimer.
38 * 2. Redistributions in binary form must reproduce the above copyright
39 * notice, this list of conditions and the following disclaimer in the
40 * documentation and/or other materials provided with the distribution.
41 * 4. Neither the name of the University nor the names of its contributors
42 * may be used to endorse or promote products derived from this software
43 * without specific prior written permission.
45 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
46 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
47 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
48 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
49 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
50 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
51 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
52 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
53 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
54 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
57 * @(#)subr_prf.c 8.3 (Berkeley) 1/21/94
61 #include <stdarg.h> // err.....
63 #include <palacios/vmm.h>
64 #include <palacios/vmm_types.h>
65 #include <palacios/vmm_string.h>
66 #include <palacios/vmm_sprintf.h>
69 #define NEED_SPRINTF 0
70 #define NEED_SNPRINTF 0
71 #define NEED_VSPRINTF 0
72 #define NEED_VSNPRINTF 0
73 #define NEED_VSNRPRINTF 1
76 typedef addr_t ptrdiff_t; /* ptr1 - ptr2 */
78 /* Max number conversion buffer length: a u_quad_t in base 2, plus NUL byte. */
79 #define MAXNBUF (sizeof(uint64_t) + 1)
82 /* convert a hex value to it's ascii representation */
83 static char const hex2ascii_data[] = "0123456789abcdefghijklmnopqrstuvwxyz";
85 #define hex2ascii(hex) (hex2ascii_data[hex])
94 static char * ksprintn(char * nbuf, uint64_t num, int base, int *len, int upper);
95 static void snprintf_func(int ch, void * arg);
96 static int kvprintf(char const * fmt, void (*func)(int, void *), void * arg, int radix, va_list ap);
101 * Scaled down version of sprintf(3).
103 int sprintf(char * buf, const char * cfmt, ...) {
108 retval = kvprintf(cfmt, NULL, (void *)buf, 10, ap);
118 * Scaled down version of vsprintf(3).
120 int vsprintf(char * buf, const char * cfmt, va_list ap) {
123 retval = kvprintf(cfmt, NULL, (void *)buf, 10, ap);
132 * Scaled down version of snprintf(3).
134 int snprintf(char * str, size_t size, const char * format, ...) {
138 va_start(ap, format);
139 retval = vsnprintf(str, size, format, ap);
148 * Scaled down version of vsnprintf(3).
150 int vsnprintf(char * str, size_t size, const char * format, va_list ap) {
151 struct snprintf_arg info;
156 retval = kvprintf(format, snprintf_func, &info, 10, ap);
157 if (info.remain >= 1) {
167 * Kernel version which takes radix argument vsnprintf(3).
169 int vsnrprintf(char * str, size_t size, int radix, const char * format, va_list ap) {
170 struct snprintf_arg info;
175 retval = kvprintf(format, snprintf_func, &info, radix, ap);
176 if (info.remain >= 1) {
184 static void snprintf_func(int ch, void *arg) {
185 struct snprintf_arg *const info = arg;
187 if (info->remain >= 2) {
194 * Put a NUL-terminated ASCII number (base <= 36) in a buffer in reverse
195 * order; return an optional length and a pointer to the last character
196 * written in the buffer (i.e., the first character of the string).
197 * The buffer pointed to by `nbuf' must have length >= MAXNBUF.
199 static char * ksprintn(char *nbuf, uint64_t num, int base, int *lenp, int upper) {
205 c = hex2ascii(num % base);
206 *++p = upper ? toupper(c) : c;
207 } while (num /= base);
214 * Scaled down version of printf(3).
216 * Two additional formats:
218 * The format %b is supported to decode error registers.
221 * printf("reg=%b\n", regval, "<base><arg>*");
223 * where <base> is the output base expressed as a control character, e.g.
224 * \10 gives octal; \20 gives hex. Each arg is a sequence of characters,
225 * the first of which gives the bit number to be inspected (origin 1), and
226 * the next characters (up to a control character, i.e. a character <= 32),
227 * give the name of the register. Thus:
229 * kvprintf("reg=%b\n", 3, "\10\2BITTWO\1BITONE\n");
231 * would produce output:
233 * reg=3<BITTWO,BITONE>
235 * XXX: %D -- Hexdump, takes pointer and separator string:
236 * ("%6D", ptr, ":") -> XX:XX:XX:XX:XX:XX
237 * ("%*D", len, ptr, " " -> XX XX XX XX ...
240 kvprintf(char const *fmt, void (*func)(int, void*), void *arg, int radix, va_list ap)
242 #define PCHAR(c) {int cc=(c); if (func) (*func)(cc,arg); else *d++ = cc; retval++; }
245 const char *p, *percent, *q;
249 int base, lflag, qflag, tmp, width, ladjust, sharpflag, neg, sign, dot;
250 int cflag, hflag, jflag, tflag, zflag;
253 int stop = 0, retval = 0;
262 fmt = "(fmt null)\n";
264 if (radix < 2 || radix > 36)
270 while ((ch = (uchar_t)*fmt++) != '%' || stop) {
276 qflag = 0; lflag = 0; ladjust = 0; sharpflag = 0; neg = 0;
277 sign = 0; dot = 0; dwidth = 0; upper = 0;
278 cflag = 0; hflag = 0; jflag = 0; tflag = 0; zflag = 0;
279 reswitch: switch (ch = (uchar_t)*fmt++) {
297 width = va_arg(ap, int);
303 dwidth = va_arg(ap, int);
311 case '1': case '2': case '3': case '4':
312 case '5': case '6': case '7': case '8': case '9':
313 for (n = 0;; ++fmt) {
314 n = n * 10 + ch - '0';
316 if (ch < '0' || ch > '9')
325 num = (uint_t)va_arg(ap, int);
326 p = va_arg(ap, char *);
327 for (q = ksprintn(nbuf, num, *p++, NULL, 0); *q;)
335 if (num & (1 << (n - 1))) {
336 PCHAR(tmp ? ',' : '<');
337 for (; (n = *p) > ' '; ++p)
341 for (; *p > ' '; ++p)
348 PCHAR(va_arg(ap, int));
351 up = va_arg(ap, uchar_t *);
352 p = va_arg(ap, char *);
356 PCHAR(hex2ascii(*up >> 4));
357 PCHAR(hex2ascii(*up & 0x0f));
389 *(va_arg(ap, sint64_t *)) = retval;
391 *(va_arg(ap, sint64_t *)) = retval;
393 *(va_arg(ap, long *)) = retval;
395 *(va_arg(ap, size_t *)) = retval;
397 *(va_arg(ap, short *)) = retval;
399 *(va_arg(ap, char *)) = retval;
401 *(va_arg(ap, int *)) = retval;
408 sharpflag = (width == 0);
410 num = (addr_t)va_arg(ap, void *);
421 p = va_arg(ap, char *);
427 for (n = 0; n < dwidth && p[n]; n++)
432 if (!ladjust && width > 0)
437 if (ladjust && width > 0)
462 num = va_arg(ap, addr_t);
464 num = va_arg(ap, uint64_t);
466 num = va_arg(ap, ptrdiff_t);
468 num = va_arg(ap, ulong_t);
470 num = va_arg(ap, size_t);
472 num = (ushort_t)va_arg(ap, int);
474 num = (uchar_t)va_arg(ap, int);
476 num = va_arg(ap, uint_t);
480 num = va_arg(ap, sint64_t);
482 num = va_arg(ap, sint64_t);
484 num = va_arg(ap, ptrdiff_t);
486 num = va_arg(ap, long);
488 num = va_arg(ap, ssize_t);
490 num = (short)va_arg(ap, int);
492 num = (char)va_arg(ap, int);
494 num = va_arg(ap, int);
496 if (sign && (sint64_t)num < 0) {
498 num = -(sint64_t)num;
500 p = ksprintn(nbuf, num, base, &tmp, upper);
501 if (sharpflag && num != 0) {
510 if (!ladjust && padc != '0' && width
511 && (width -= tmp) > 0)
516 if (sharpflag && num != 0) {
519 } else if (base == 16) {
524 if (!ladjust && width && (width -= tmp) > 0)
531 if (ladjust && width && (width -= tmp) > 0)
537 while (percent < fmt)
540 * Since we ignore an formatting argument it is no
541 * longer safe to obey the remaining formatting
542 * arguments as the arguments will no longer match
555 void v3_hexdump(const void * ptr, int length, const char * hdr, int flags) {
558 const unsigned char *cp;
561 if ((flags & HD_DELIM_MASK) != 0)
562 delim = (flags & HD_DELIM_MASK) >> 8;
566 if ((flags & HD_COLUMN_MASK) != 0)
567 cols = flags & HD_COLUMN_MASK;
572 for (i = 0; i < length; i+= cols) {
574 PrintDebug("%s", hdr);
576 if ((flags & HD_OMIT_COUNT) == 0)
577 PrintDebug("%04x ", i);
579 if ((flags & HD_OMIT_HEX) == 0) {
580 for (j = 0; j < cols; j++) {
583 PrintDebug("%c%02x", delim, cp[k]);
589 if ((flags & HD_OMIT_CHARS) == 0) {
591 for (j = 0; j < cols; j++) {
595 else if (cp[k] >= ' ' && cp[k] <= '~')
596 PrintDebug("%c", cp[k]);