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>
71 typedef addr_t ptrdiff_t; /* ptr1 - ptr2 */
73 /* Max number conversion buffer length: a u_quad_t in base 2, plus NUL byte. */
74 #define MAXNBUF (sizeof(uint64_t) + 1)
77 /* convert a hex value to it's ascii representation */
78 static char const hex2ascii_data[] = "0123456789abcdefghijklmnopqrstuvwxyz";
80 #define hex2ascii(hex) (hex2ascii_data[hex])
90 #if defined(CONFIG_BUILT_IN_STDIO) && \
91 ( defined(CONFIG_BUILT_IN_SPRINTF) || \
92 defined(CONFIG_BUILT_IN_SNPRINTF) || \
93 defined(CONFIG_BUILT_IN_VSPRINTF) || \
94 defined(CONFIG_BUILT_IN_VSNPRINTF) || \
95 defined(CONFIG_BUILT_IN_VSNRPRINTF ))
97 static char * ksprintn(char * nbuf, uint64_t num, int base, int *len, int upper);
98 static void snprintf_func(int ch, void * arg);
99 static int kvprintf(char const * fmt, void (*func)(int, void *), void * arg, int radix, va_list ap);
102 #ifdef CONFIG_BUILT_IN_SPRINTF
104 * Scaled down version of sprintf(3).
106 int sprintf(char * buf, const char * cfmt, ...) {
111 retval = kvprintf(cfmt, NULL, (void *)buf, 10, ap);
119 #ifdef CONFIG_BUILT_IN_VSPRINTF
121 * Scaled down version of vsprintf(3).
123 int vsprintf(char * buf, const char * cfmt, va_list ap) {
126 retval = kvprintf(cfmt, NULL, (void *)buf, 10, ap);
133 #ifdef CONFIG_BUILT_IN_SNPRINTF
135 * Scaled down version of snprintf(3).
137 int snprintf(char * str, size_t size, const char * format, ...) {
141 va_start(ap, format);
142 retval = vsnprintf(str, size, format, ap);
149 #ifdef CONFIG_BUILT_IN_VSNPRINTF
151 * Scaled down version of vsnprintf(3).
153 int vsnprintf(char * str, size_t size, const char * format, va_list ap) {
154 struct snprintf_arg info;
159 retval = kvprintf(format, snprintf_func, &info, 10, ap);
160 if (info.remain >= 1) {
168 #ifdef CONFIG_BUILT_IN_VSNRPRINTF
170 * Kernel version which takes radix argument vsnprintf(3).
172 int vsnrprintf(char * str, size_t size, int radix, const char * format, va_list ap) {
173 struct snprintf_arg info;
178 retval = kvprintf(format, snprintf_func, &info, radix, ap);
179 if (info.remain >= 1) {
187 static void snprintf_func(int ch, void *arg) {
188 struct snprintf_arg *const info = arg;
190 if (info->remain >= 2) {
197 * Put a NUL-terminated ASCII number (base <= 36) in a buffer in reverse
198 * order; return an optional length and a pointer to the last character
199 * written in the buffer (i.e., the first character of the string).
200 * The buffer pointed to by `nbuf' must have length >= MAXNBUF.
202 static char * ksprintn(char *nbuf, uint64_t num, int base, int *lenp, int upper) {
208 c = hex2ascii(num % base);
209 *++p = upper ? toupper(c) : c;
210 } while (num /= base);
217 * Scaled down version of printf(3).
219 * Two additional formats:
221 * The format %b is supported to decode error registers.
224 * printf("reg=%b\n", regval, "<base><arg>*");
226 * where <base> is the output base expressed as a control character, e.g.
227 * \10 gives octal; \20 gives hex. Each arg is a sequence of characters,
228 * the first of which gives the bit number to be inspected (origin 1), and
229 * the next characters (up to a control character, i.e. a character <= 32),
230 * give the name of the register. Thus:
232 * kvprintf("reg=%b\n", 3, "\10\2BITTWO\1BITONE\n");
234 * would produce output:
236 * reg=3<BITTWO,BITONE>
238 * XXX: %D -- Hexdump, takes pointer and separator string:
239 * ("%6D", ptr, ":") -> XX:XX:XX:XX:XX:XX
240 * ("%*D", len, ptr, " " -> XX XX XX XX ...
243 kvprintf(char const *fmt, void (*func)(int, void*), void *arg, int radix, va_list ap)
245 #define PCHAR(c) {int cc=(c); if (func) (*func)(cc,arg); else *d++ = cc; retval++; }
248 const char *p, *percent, *q;
252 int base, lflag, qflag, tmp, width, ladjust, sharpflag, neg, sign, dot;
253 int cflag, hflag, jflag, tflag, zflag;
256 int stop = 0, retval = 0;
265 fmt = "(fmt null)\n";
267 if (radix < 2 || radix > 36)
273 while ((ch = (uchar_t)*fmt++) != '%' || stop) {
279 qflag = 0; lflag = 0; ladjust = 0; sharpflag = 0; neg = 0;
280 sign = 0; dot = 0; dwidth = 0; upper = 0;
281 cflag = 0; hflag = 0; jflag = 0; tflag = 0; zflag = 0;
282 reswitch: switch (ch = (uchar_t)*fmt++) {
300 width = va_arg(ap, int);
306 dwidth = va_arg(ap, int);
314 case '1': case '2': case '3': case '4':
315 case '5': case '6': case '7': case '8': case '9':
316 for (n = 0;; ++fmt) {
317 n = n * 10 + ch - '0';
319 if (ch < '0' || ch > '9')
328 num = (uint_t)va_arg(ap, int);
329 p = va_arg(ap, char *);
330 for (q = ksprintn(nbuf, num, *p++, NULL, 0); *q;)
338 if (num & (1 << (n - 1))) {
339 PCHAR(tmp ? ',' : '<');
340 for (; (n = *p) > ' '; ++p)
344 for (; *p > ' '; ++p)
351 PCHAR(va_arg(ap, int));
354 up = va_arg(ap, uchar_t *);
355 p = va_arg(ap, char *);
359 PCHAR(hex2ascii(*up >> 4));
360 PCHAR(hex2ascii(*up & 0x0f));
392 *(va_arg(ap, sint64_t *)) = retval;
394 *(va_arg(ap, sint64_t *)) = retval;
396 *(va_arg(ap, long *)) = retval;
398 *(va_arg(ap, size_t *)) = retval;
400 *(va_arg(ap, short *)) = retval;
402 *(va_arg(ap, char *)) = retval;
404 *(va_arg(ap, int *)) = retval;
411 sharpflag = (width == 0);
413 num = (addr_t)va_arg(ap, void *);
424 p = va_arg(ap, char *);
430 for (n = 0; n < dwidth && p[n]; n++)
435 if (!ladjust && width > 0)
440 if (ladjust && width > 0)
465 num = va_arg(ap, addr_t);
467 num = va_arg(ap, uint64_t);
469 num = va_arg(ap, ptrdiff_t);
471 num = va_arg(ap, ulong_t);
473 num = va_arg(ap, size_t);
475 num = (ushort_t)va_arg(ap, int);
477 num = (uchar_t)va_arg(ap, int);
479 num = va_arg(ap, uint_t);
483 num = va_arg(ap, sint64_t);
485 num = va_arg(ap, sint64_t);
487 num = va_arg(ap, ptrdiff_t);
489 num = va_arg(ap, long);
491 num = va_arg(ap, ssize_t);
493 num = (short)va_arg(ap, int);
495 num = (char)va_arg(ap, int);
497 num = va_arg(ap, int);
499 if (sign && (sint64_t)num < 0) {
501 num = -(sint64_t)num;
503 p = ksprintn(nbuf, num, base, &tmp, upper);
504 if (sharpflag && num != 0) {
513 if (!ladjust && padc != '0' && width
514 && (width -= tmp) > 0)
519 if (sharpflag && num != 0) {
522 } else if (base == 16) {
527 if (!ladjust && width && (width -= tmp) > 0)
534 if (ladjust && width && (width -= tmp) > 0)
540 while (percent < fmt)
543 * Since we ignore an formatting argument it is no
544 * longer safe to obey the remaining formatting
545 * arguments as the arguments will no longer match
556 #endif // CONFIG_BUILT_IN_STDIO
560 void v3_hexdump(const void * ptr, int length, const char * hdr, int flags) {
563 const unsigned char *cp;
566 if ((flags & HD_DELIM_MASK) != 0)
567 delim = (flags & HD_DELIM_MASK) >> 8;
571 if ((flags & HD_COLUMN_MASK) != 0)
572 cols = flags & HD_COLUMN_MASK;
577 for (i = 0; i < length; i+= cols) {
581 if ((flags & HD_OMIT_COUNT) == 0)
582 V3_Print("%04x ", i);
584 if ((flags & HD_OMIT_HEX) == 0) {
585 for (j = 0; j < cols; j++) {
588 V3_Print("%c%02x", delim, cp[k]);
594 if ((flags & HD_OMIT_CHARS) == 0) {
596 for (j = 0; j < cols; j++) {
600 else if (cp[k] >= ' ' && cp[k] <= '~')
601 V3_Print("%c", cp[k]);