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(V3_CONFIG_BUILT_IN_STDIO) && \
91 ( defined(V3_CONFIG_BUILT_IN_SPRINTF) || \
92 defined(V3_CONFIG_BUILT_IN_SNPRINTF) || \
93 defined(V3_CONFIG_BUILT_IN_VSPRINTF) || \
94 defined(V3_CONFIG_BUILT_IN_VSNRPRINTF ))
96 static char * ksprintn(char * nbuf, uint64_t num, int base, int *len, int upper);
97 static void snprintf_func(int ch, void * arg);
98 static int kvprintf(char const * fmt, void (*func)(int, void *), void * arg, int radix, va_list ap);
101 #ifdef V3_CONFIG_BUILT_IN_SPRINTF
103 * Scaled down version of sprintf(3).
105 int sprintf(char * buf, const char * cfmt, ...) {
110 retval = kvprintf(cfmt, NULL, (void *)buf, 10, ap);
118 #ifdef V3_CONFIG_BUILT_IN_VSPRINTF
120 * Scaled down version of vsprintf(3).
122 int vsprintf(char * buf, const char * cfmt, va_list ap) {
125 retval = kvprintf(cfmt, NULL, (void *)buf, 10, ap);
132 #ifdef V3_CONFIG_BUILT_IN_SNPRINTF
134 * Scaled down version of snprintf(3).
136 int snprintf(char * str, size_t size, const char * format, ...) {
140 va_start(ap, format);
141 retval = vsnprintf(str, size, format, ap);
150 * Scaled down version of vsnprintf(3).
152 int vsnprintf(char * str, size_t size, const char * format, va_list ap) {
153 struct snprintf_arg info;
158 retval = kvprintf(format, snprintf_func, &info, 10, ap);
159 if (info.remain >= 1) {
167 #ifdef V3_CONFIG_BUILT_IN_VSNRPRINTF
169 * Kernel version which takes radix argument vsnprintf(3).
171 int vsnrprintf(char * str, size_t size, int radix, const char * format, va_list ap) {
172 struct snprintf_arg info;
177 retval = kvprintf(format, snprintf_func, &info, radix, ap);
178 if (info.remain >= 1) {
186 static void snprintf_func(int ch, void *arg) {
187 struct snprintf_arg *const info = arg;
189 if (info->remain >= 2) {
196 * Put a NUL-terminated ASCII number (base <= 36) in a buffer in reverse
197 * order; return an optional length and a pointer to the last character
198 * written in the buffer (i.e., the first character of the string).
199 * The buffer pointed to by `nbuf' must have length >= MAXNBUF.
201 static char * ksprintn(char *nbuf, uint64_t num, int base, int *lenp, int upper) {
207 c = hex2ascii(num % base);
208 *++p = upper ? toupper(c) : c;
209 } while (num /= base);
216 * Scaled down version of printf(3).
218 * Two additional formats:
220 * The format %b is supported to decode error registers.
223 * printf("reg=%b\n", regval, "<base><arg>*");
225 * where <base> is the output base expressed as a control character, e.g.
226 * \10 gives octal; \20 gives hex. Each arg is a sequence of characters,
227 * the first of which gives the bit number to be inspected (origin 1), and
228 * the next characters (up to a control character, i.e. a character <= 32),
229 * give the name of the register. Thus:
231 * kvprintf("reg=%b\n", 3, "\10\2BITTWO\1BITONE\n");
233 * would produce output:
235 * reg=3<BITTWO,BITONE>
237 * XXX: %D -- Hexdump, takes pointer and separator string:
238 * ("%6D", ptr, ":") -> XX:XX:XX:XX:XX:XX
239 * ("%*D", len, ptr, " " -> XX XX XX XX ...
242 kvprintf(char const *fmt, void (*func)(int, void*), void *arg, int radix, va_list ap)
244 #define PCHAR(c) {int cc=(c); if (func) (*func)(cc,arg); else *d++ = cc; retval++; }
247 const char *p, *percent, *q;
251 int base, lflag, qflag, tmp, width, ladjust, sharpflag, neg, sign, dot;
252 int cflag, hflag, jflag, tflag, zflag;
255 int stop = 0, retval = 0;
264 fmt = "(fmt null)\n";
266 if (radix < 2 || radix > 36)
272 while ((ch = (uchar_t)*fmt++) != '%' || stop) {
278 qflag = 0; lflag = 0; ladjust = 0; sharpflag = 0; neg = 0;
279 sign = 0; dot = 0; dwidth = 0; upper = 0;
280 cflag = 0; hflag = 0; jflag = 0; tflag = 0; zflag = 0;
281 reswitch: switch (ch = (uchar_t)*fmt++) {
299 width = va_arg(ap, int);
305 dwidth = va_arg(ap, int);
313 case '1': case '2': case '3': case '4':
314 case '5': case '6': case '7': case '8': case '9':
315 for (n = 0;; ++fmt) {
316 n = n * 10 + ch - '0';
318 if (ch < '0' || ch > '9')
327 num = (uint_t)va_arg(ap, int);
328 p = va_arg(ap, char *);
329 for (q = ksprintn(nbuf, num, *p++, NULL, 0); *q;)
337 if (num & (1 << (n - 1))) {
338 PCHAR(tmp ? ',' : '<');
339 for (; (n = *p) > ' '; ++p)
343 for (; *p > ' '; ++p)
350 PCHAR(va_arg(ap, int));
353 up = va_arg(ap, uchar_t *);
354 p = va_arg(ap, char *);
358 PCHAR(hex2ascii(*up >> 4));
359 PCHAR(hex2ascii(*up & 0x0f));
391 *(va_arg(ap, sint64_t *)) = retval;
393 *(va_arg(ap, sint64_t *)) = retval;
395 *(va_arg(ap, long *)) = retval;
397 *(va_arg(ap, size_t *)) = retval;
399 *(va_arg(ap, short *)) = retval;
401 *(va_arg(ap, char *)) = retval;
403 *(va_arg(ap, int *)) = retval;
410 sharpflag = (width == 0);
412 num = (addr_t)va_arg(ap, void *);
423 p = va_arg(ap, char *);
429 for (n = 0; n < dwidth && p[n]; n++)
434 if (!ladjust && width > 0)
439 if (ladjust && width > 0)
464 num = va_arg(ap, addr_t);
466 num = va_arg(ap, uint64_t);
468 num = va_arg(ap, ptrdiff_t);
470 num = va_arg(ap, ulong_t);
472 num = va_arg(ap, size_t);
474 num = (ushort_t)va_arg(ap, int);
476 num = (uchar_t)va_arg(ap, int);
478 num = va_arg(ap, uint_t);
482 num = va_arg(ap, sint64_t);
484 num = va_arg(ap, sint64_t);
486 num = va_arg(ap, ptrdiff_t);
488 num = va_arg(ap, long);
490 num = va_arg(ap, ssize_t);
492 num = (short)va_arg(ap, int);
494 num = (char)va_arg(ap, int);
496 num = va_arg(ap, int);
498 if (sign && (sint64_t)num < 0) {
500 num = -(sint64_t)num;
502 p = ksprintn(nbuf, num, base, &tmp, upper);
503 if (sharpflag && num != 0) {
512 if (!ladjust && padc != '0' && width
513 && (width -= tmp) > 0)
518 if (sharpflag && num != 0) {
521 } else if (base == 16) {
526 if (!ladjust && width && (width -= tmp) > 0)
533 if (ladjust && width && (width -= tmp) > 0)
539 while (percent < fmt)
542 * Since we ignore an formatting argument it is no
543 * longer safe to obey the remaining formatting
544 * arguments as the arguments will no longer match
555 #endif // V3_CONFIG_BUILT_IN_STDIO
559 void v3_hexdump(const void * ptr, int length, const char * hdr, int flags) {
562 const unsigned char *cp;
565 if ((flags & HD_DELIM_MASK) != 0)
566 delim = (flags & HD_DELIM_MASK) >> 8;
570 if ((flags & HD_COLUMN_MASK) != 0)
571 cols = flags & HD_COLUMN_MASK;
576 for (i = 0; i < length; i+= cols) {
580 if ((flags & HD_OMIT_COUNT) == 0)
581 V3_Print("%04x ", i);
583 if ((flags & HD_OMIT_HEX) == 0) {
584 for (j = 0; j < cols; j++) {
587 V3_Print("%c%02x", delim, cp[k]);
593 if ((flags & HD_OMIT_CHARS) == 0) {
595 for (j = 0; j < cols; j++) {
599 else if (cp[k] >= ' ' && cp[k] <= '~')
600 V3_Print("%c", cp[k]);