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])
89 static char * ksprintn(char * nbuf, uint64_t num, int base, int *len, int upper);
90 static void snprintf_func(int ch, void * arg);
91 static int kvprintf(char const * fmt, void (*func)(int, void *), void * arg, int radix, va_list ap);
94 #ifdef CONFIG_BUILT_IN_SPRINTF
96 * Scaled down version of sprintf(3).
98 int sprintf(char * buf, const char * cfmt, ...) {
103 retval = kvprintf(cfmt, NULL, (void *)buf, 10, ap);
111 #ifdef CONFIG_BUILT_IN_VSPRINTF
113 * Scaled down version of vsprintf(3).
115 int vsprintf(char * buf, const char * cfmt, va_list ap) {
118 retval = kvprintf(cfmt, NULL, (void *)buf, 10, ap);
125 #ifdef CONFIG_BUILT_IN_SNPRINTF
127 * Scaled down version of snprintf(3).
129 int snprintf(char * str, size_t size, const char * format, ...) {
133 va_start(ap, format);
134 retval = vsnprintf(str, size, format, ap);
141 #ifdef CONFIG_BUILT_IN_VSNPRINTF
143 * Scaled down version of vsnprintf(3).
145 int vsnprintf(char * str, size_t size, const char * format, va_list ap) {
146 struct snprintf_arg info;
151 retval = kvprintf(format, snprintf_func, &info, 10, ap);
152 if (info.remain >= 1) {
160 #ifdef CONFIG_BUILT_IN_VSNRPRINTF
162 * Kernel version which takes radix argument vsnprintf(3).
164 int vsnrprintf(char * str, size_t size, int radix, const char * format, va_list ap) {
165 struct snprintf_arg info;
170 retval = kvprintf(format, snprintf_func, &info, radix, ap);
171 if (info.remain >= 1) {
179 static void snprintf_func(int ch, void *arg) {
180 struct snprintf_arg *const info = arg;
182 if (info->remain >= 2) {
189 * Put a NUL-terminated ASCII number (base <= 36) in a buffer in reverse
190 * order; return an optional length and a pointer to the last character
191 * written in the buffer (i.e., the first character of the string).
192 * The buffer pointed to by `nbuf' must have length >= MAXNBUF.
194 static char * ksprintn(char *nbuf, uint64_t num, int base, int *lenp, int upper) {
200 c = hex2ascii(num % base);
201 *++p = upper ? toupper(c) : c;
202 } while (num /= base);
209 * Scaled down version of printf(3).
211 * Two additional formats:
213 * The format %b is supported to decode error registers.
216 * printf("reg=%b\n", regval, "<base><arg>*");
218 * where <base> is the output base expressed as a control character, e.g.
219 * \10 gives octal; \20 gives hex. Each arg is a sequence of characters,
220 * the first of which gives the bit number to be inspected (origin 1), and
221 * the next characters (up to a control character, i.e. a character <= 32),
222 * give the name of the register. Thus:
224 * kvprintf("reg=%b\n", 3, "\10\2BITTWO\1BITONE\n");
226 * would produce output:
228 * reg=3<BITTWO,BITONE>
230 * XXX: %D -- Hexdump, takes pointer and separator string:
231 * ("%6D", ptr, ":") -> XX:XX:XX:XX:XX:XX
232 * ("%*D", len, ptr, " " -> XX XX XX XX ...
235 kvprintf(char const *fmt, void (*func)(int, void*), void *arg, int radix, va_list ap)
237 #define PCHAR(c) {int cc=(c); if (func) (*func)(cc,arg); else *d++ = cc; retval++; }
240 const char *p, *percent, *q;
244 int base, lflag, qflag, tmp, width, ladjust, sharpflag, neg, sign, dot;
245 int cflag, hflag, jflag, tflag, zflag;
248 int stop = 0, retval = 0;
257 fmt = "(fmt null)\n";
259 if (radix < 2 || radix > 36)
265 while ((ch = (uchar_t)*fmt++) != '%' || stop) {
271 qflag = 0; lflag = 0; ladjust = 0; sharpflag = 0; neg = 0;
272 sign = 0; dot = 0; dwidth = 0; upper = 0;
273 cflag = 0; hflag = 0; jflag = 0; tflag = 0; zflag = 0;
274 reswitch: switch (ch = (uchar_t)*fmt++) {
292 width = va_arg(ap, int);
298 dwidth = va_arg(ap, int);
306 case '1': case '2': case '3': case '4':
307 case '5': case '6': case '7': case '8': case '9':
308 for (n = 0;; ++fmt) {
309 n = n * 10 + ch - '0';
311 if (ch < '0' || ch > '9')
320 num = (uint_t)va_arg(ap, int);
321 p = va_arg(ap, char *);
322 for (q = ksprintn(nbuf, num, *p++, NULL, 0); *q;)
330 if (num & (1 << (n - 1))) {
331 PCHAR(tmp ? ',' : '<');
332 for (; (n = *p) > ' '; ++p)
336 for (; *p > ' '; ++p)
343 PCHAR(va_arg(ap, int));
346 up = va_arg(ap, uchar_t *);
347 p = va_arg(ap, char *);
351 PCHAR(hex2ascii(*up >> 4));
352 PCHAR(hex2ascii(*up & 0x0f));
384 *(va_arg(ap, sint64_t *)) = retval;
386 *(va_arg(ap, sint64_t *)) = retval;
388 *(va_arg(ap, long *)) = retval;
390 *(va_arg(ap, size_t *)) = retval;
392 *(va_arg(ap, short *)) = retval;
394 *(va_arg(ap, char *)) = retval;
396 *(va_arg(ap, int *)) = retval;
403 sharpflag = (width == 0);
405 num = (addr_t)va_arg(ap, void *);
416 p = va_arg(ap, char *);
422 for (n = 0; n < dwidth && p[n]; n++)
427 if (!ladjust && width > 0)
432 if (ladjust && width > 0)
457 num = va_arg(ap, addr_t);
459 num = va_arg(ap, uint64_t);
461 num = va_arg(ap, ptrdiff_t);
463 num = va_arg(ap, ulong_t);
465 num = va_arg(ap, size_t);
467 num = (ushort_t)va_arg(ap, int);
469 num = (uchar_t)va_arg(ap, int);
471 num = va_arg(ap, uint_t);
475 num = va_arg(ap, sint64_t);
477 num = va_arg(ap, sint64_t);
479 num = va_arg(ap, ptrdiff_t);
481 num = va_arg(ap, long);
483 num = va_arg(ap, ssize_t);
485 num = (short)va_arg(ap, int);
487 num = (char)va_arg(ap, int);
489 num = va_arg(ap, int);
491 if (sign && (sint64_t)num < 0) {
493 num = -(sint64_t)num;
495 p = ksprintn(nbuf, num, base, &tmp, upper);
496 if (sharpflag && num != 0) {
505 if (!ladjust && padc != '0' && width
506 && (width -= tmp) > 0)
511 if (sharpflag && num != 0) {
514 } else if (base == 16) {
519 if (!ladjust && width && (width -= tmp) > 0)
526 if (ladjust && width && (width -= tmp) > 0)
532 while (percent < fmt)
535 * Since we ignore an formatting argument it is no
536 * longer safe to obey the remaining formatting
537 * arguments as the arguments will no longer match
550 void v3_hexdump(const void * ptr, int length, const char * hdr, int flags) {
553 const unsigned char *cp;
556 if ((flags & HD_DELIM_MASK) != 0)
557 delim = (flags & HD_DELIM_MASK) >> 8;
561 if ((flags & HD_COLUMN_MASK) != 0)
562 cols = flags & HD_COLUMN_MASK;
567 for (i = 0; i < length; i+= cols) {
569 PrintDebug("%s", hdr);
571 if ((flags & HD_OMIT_COUNT) == 0)
572 PrintDebug("%04x ", i);
574 if ((flags & HD_OMIT_HEX) == 0) {
575 for (j = 0; j < cols; j++) {
578 PrintDebug("%c%02x", delim, cp[k]);
584 if ((flags & HD_OMIT_CHARS) == 0) {
586 for (j = 0; j < cols; j++) {
590 else if (cp[k] >= ' ' && cp[k] <= '~')
591 PrintDebug("%c", cp[k]);