11.1Schristos/*-
21.1Schristos * Copyright (c) 2017 The NetBSD Foundation, Inc.
31.1Schristos * All rights reserved.
41.1Schristos *
51.1Schristos * This code is derived from software contributed to The NetBSD Foundation
61.1Schristos * by Christos Zoulas.
71.1Schristos *
81.1Schristos * Redistribution and use in source and binary forms, with or without
91.1Schristos * modification, are permitted provided that the following conditions
101.1Schristos * are met:
111.1Schristos * 1. Redistributions of source code must retain the above copyright
121.1Schristos *    notice, this list of conditions and the following disclaimer.
131.1Schristos * 2. Redistributions in binary form must reproduce the above copyright
141.1Schristos *    notice, this list of conditions and the following disclaimer in the
151.1Schristos *    documentation and/or other materials provided with the distribution.
161.1Schristos *
171.1Schristos * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
181.1Schristos * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
191.1Schristos * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
201.1Schristos * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
211.1Schristos * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
221.1Schristos * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
231.1Schristos * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
241.1Schristos * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
251.1Schristos * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
261.1Schristos * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
271.1Schristos * POSSIBILITY OF SUCH DAMAGE.
281.1Schristos */
291.1Schristos#include <sys/cdefs.h>
301.4Schristos__KERNEL_RCSID(0, "$NetBSD: hexdump.c,v 1.4 2017/12/09 00:51:52 christos Exp $");
311.1Schristos
321.3Schristos#ifdef DEBUG_HEXDUMP
331.2Schristos#include <stdio.h>
341.2Schristos#include <ctype.h>
351.2Schristos#include <string.h>
361.2Schristos#include <stdlib.h>
371.4Schristos#define RET int
381.2Schristosstatic const char hexdigits[] = "0123456789abcdef";
391.2Schristos#else
401.4Schristos#define RET void
411.1Schristos#include <lib/libkern/libkern.h>
421.1Schristos#include <sys/systm.h>
431.2Schristos#endif
441.2Schristos
451.2Schristos#define MID (3 * 8)
461.2Schristos#define BAR ((3 * 16) + 1)
471.2Schristos#define ASC (BAR + 2)
481.2Schristos#define NL (BAR + 18)
491.1Schristos
501.1Schristosvoid
511.4Schristoshexdump(RET (*pr)(const char *, ...) __printflike(1, 2), const char *msg,
521.4Schristos    const void *ptr, size_t len)
531.1Schristos{
541.2Schristos	size_t i, p, q;
551.1Schristos	const unsigned char *u = ptr;
561.2Schristos	char buf[NL + 2];
571.1Schristos
581.1Schristos	if (msg)
591.4Schristos		(*pr)("%s: %zu bytes @ %p\n", msg, len, ptr);
601.2Schristos
611.2Schristos	buf[BAR] = '|';
621.2Schristos	buf[BAR + 1] = ' ';
631.2Schristos	buf[NL] = '\n';
641.2Schristos	buf[NL + 1] = '\0';
651.2Schristos        for (q = p = i = 0; i < len; i++) {
661.2Schristos		unsigned char c = u[i];
671.2Schristos		buf[p++] = hexdigits[(c >> 4) & 0xf];
681.2Schristos		buf[p++] = hexdigits[(c >> 0) & 0xf];
691.2Schristos		buf[p++] = ' ';
701.2Schristos                if (q == 7)
711.2Schristos		       buf[p++] = ' ';
721.2Schristos
731.2Schristos		buf[ASC + q++] = isprint(c) ? c : '.';
741.2Schristos
751.2Schristos		if (q == 16) {
761.2Schristos			q = p = 0;
771.4Schristos			(*pr)("%s", buf);
781.1Schristos		}
791.1Schristos        }
801.2Schristos	if (q) {
811.4Schristos		while (p < BAR)
821.4Schristos			buf[p++] = ' ';
831.2Schristos		buf[ASC + q++] = '\n';
841.2Schristos		buf[ASC + q] = '\0';
851.4Schristos		(*pr)("%s", buf);
861.2Schristos	}
871.2Schristos}
881.2Schristos
891.3Schristos#ifdef DEBUG_HEXDUMP
901.2Schristosint
911.2Schristosmain(int argc, char *argv[])
921.2Schristos{
931.4Schristos	hexdump(printf, "foo", main, atoi(argv[1]));
941.2Schristos	return 0;
951.1Schristos}
961.2Schristos#endif
97