xref: /netbsd-src/sys/lib/libkern/hexdump.c (revision 489063e9bc954dec6cf273a7913f6a1ddfda4956)
14a1f5c48Schristos /*-
24a1f5c48Schristos  * Copyright (c) 2017 The NetBSD Foundation, Inc.
34a1f5c48Schristos  * All rights reserved.
44a1f5c48Schristos  *
54a1f5c48Schristos  * This code is derived from software contributed to The NetBSD Foundation
64a1f5c48Schristos  * by Christos Zoulas.
74a1f5c48Schristos  *
84a1f5c48Schristos  * Redistribution and use in source and binary forms, with or without
94a1f5c48Schristos  * modification, are permitted provided that the following conditions
104a1f5c48Schristos  * are met:
114a1f5c48Schristos  * 1. Redistributions of source code must retain the above copyright
124a1f5c48Schristos  *    notice, this list of conditions and the following disclaimer.
134a1f5c48Schristos  * 2. Redistributions in binary form must reproduce the above copyright
144a1f5c48Schristos  *    notice, this list of conditions and the following disclaimer in the
154a1f5c48Schristos  *    documentation and/or other materials provided with the distribution.
164a1f5c48Schristos  *
174a1f5c48Schristos  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
184a1f5c48Schristos  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
194a1f5c48Schristos  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
204a1f5c48Schristos  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
214a1f5c48Schristos  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
224a1f5c48Schristos  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
234a1f5c48Schristos  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
244a1f5c48Schristos  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
254a1f5c48Schristos  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
264a1f5c48Schristos  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
274a1f5c48Schristos  * POSSIBILITY OF SUCH DAMAGE.
284a1f5c48Schristos  */
294a1f5c48Schristos #include <sys/cdefs.h>
30*489063e9Schristos __KERNEL_RCSID(0, "$NetBSD: hexdump.c,v 1.4 2017/12/09 00:51:52 christos Exp $");
314a1f5c48Schristos 
32cbb79c44Schristos #ifdef DEBUG_HEXDUMP
33f0d31504Schristos #include <stdio.h>
34f0d31504Schristos #include <ctype.h>
35f0d31504Schristos #include <string.h>
36f0d31504Schristos #include <stdlib.h>
37*489063e9Schristos #define RET int
38f0d31504Schristos static const char hexdigits[] = "0123456789abcdef";
39f0d31504Schristos #else
40*489063e9Schristos #define RET void
414a1f5c48Schristos #include <lib/libkern/libkern.h>
424a1f5c48Schristos #include <sys/systm.h>
43f0d31504Schristos #endif
44f0d31504Schristos 
45f0d31504Schristos #define MID (3 * 8)
46f0d31504Schristos #define BAR ((3 * 16) + 1)
47f0d31504Schristos #define ASC (BAR + 2)
48f0d31504Schristos #define NL (BAR + 18)
494a1f5c48Schristos 
504a1f5c48Schristos void
51*489063e9Schristos hexdump(RET (*pr)(const char *, ...) __printflike(1, 2), const char *msg,
52*489063e9Schristos     const void *ptr, size_t len)
534a1f5c48Schristos {
54f0d31504Schristos 	size_t i, p, q;
554a1f5c48Schristos 	const unsigned char *u = ptr;
56f0d31504Schristos 	char buf[NL + 2];
574a1f5c48Schristos 
584a1f5c48Schristos 	if (msg)
59*489063e9Schristos 		(*pr)("%s: %zu bytes @ %p\n", msg, len, ptr);
60f0d31504Schristos 
61f0d31504Schristos 	buf[BAR] = '|';
62f0d31504Schristos 	buf[BAR + 1] = ' ';
63f0d31504Schristos 	buf[NL] = '\n';
64f0d31504Schristos 	buf[NL + 1] = '\0';
65f0d31504Schristos         for (q = p = i = 0; i < len; i++) {
66f0d31504Schristos 		unsigned char c = u[i];
67f0d31504Schristos 		buf[p++] = hexdigits[(c >> 4) & 0xf];
68f0d31504Schristos 		buf[p++] = hexdigits[(c >> 0) & 0xf];
69f0d31504Schristos 		buf[p++] = ' ';
70f0d31504Schristos                 if (q == 7)
71f0d31504Schristos 		       buf[p++] = ' ';
72f0d31504Schristos 
73f0d31504Schristos 		buf[ASC + q++] = isprint(c) ? c : '.';
74f0d31504Schristos 
75f0d31504Schristos 		if (q == 16) {
76f0d31504Schristos 			q = p = 0;
77*489063e9Schristos 			(*pr)("%s", buf);
784a1f5c48Schristos 		}
794a1f5c48Schristos         }
80f0d31504Schristos 	if (q) {
81*489063e9Schristos 		while (p < BAR)
82*489063e9Schristos 			buf[p++] = ' ';
83f0d31504Schristos 		buf[ASC + q++] = '\n';
84f0d31504Schristos 		buf[ASC + q] = '\0';
85*489063e9Schristos 		(*pr)("%s", buf);
864a1f5c48Schristos 	}
874a1f5c48Schristos }
88f0d31504Schristos 
89cbb79c44Schristos #ifdef DEBUG_HEXDUMP
90f0d31504Schristos int
main(int argc,char * argv[])91f0d31504Schristos main(int argc, char *argv[])
92f0d31504Schristos {
93*489063e9Schristos 	hexdump(printf, "foo", main, atoi(argv[1]));
94f0d31504Schristos 	return 0;
95f0d31504Schristos }
96f0d31504Schristos #endif
97