1294582Sjilles/*-
2294582Sjilles * Copyright (c) 2012 Alistair Crooks <agc@NetBSD.org>
3294582Sjilles * All rights reserved.
4294582Sjilles *
5294582Sjilles * Redistribution and use in source and binary forms, with or without
6294582Sjilles * modification, are permitted provided that the following conditions
7294582Sjilles * are met:
8294582Sjilles * 1. Redistributions of source code must retain the above copyright
9294582Sjilles *    notice, this list of conditions and the following disclaimer.
10294582Sjilles * 2. Redistributions in binary form must reproduce the above copyright
11 *    notice, this list of conditions and the following disclaimer in the
12 *    documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
15 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
18 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
19 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
20 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
21 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25#include <inttypes.h>
26#include <stdio.h>
27#include <stdlib.h>
28#include <string.h>
29#include <unistd.h>
30
31#ifndef isprint
32#define isprint(x)	((x) >= ' ' && (x) <= '~')
33#endif
34
35#define HEXDUMP_LINELEN	16
36
37#ifndef PRIsize
38#define PRIsize	"z"
39#endif
40
41/* show hexadecimal/ascii dump */
42static ssize_t
43hexdump(const char *in, const size_t len, void *outvp, size_t size)
44{
45	size_t	 i;
46	char	 line[HEXDUMP_LINELEN + 1];
47	char	*out = (char *)outvp;
48	int	 o;
49
50	for (i = 0, o = 0 ; i < len ; i++) {
51		if (i % HEXDUMP_LINELEN == 0) {
52			o += snprintf(&out[o], size - o,
53					"%.5" PRIsize "u |  ", i);
54		}
55		o += snprintf(&out[o], size - o, "%.02x ", (uint8_t)in[i]);
56		line[i % HEXDUMP_LINELEN] =
57			(isprint((uint8_t)in[i])) ? in[i] : '.';
58		if (i % HEXDUMP_LINELEN == HEXDUMP_LINELEN - 1) {
59			line[HEXDUMP_LINELEN] = 0x0;
60			o += snprintf(&out[o], size - o, " | %s\n", line);
61		}
62	}
63	if (i % HEXDUMP_LINELEN != 0) {
64		for ( ; i % HEXDUMP_LINELEN != 0 ; i++) {
65			o += snprintf(&out[o], size - o, "   ");
66			line[i % HEXDUMP_LINELEN] = ' ';
67		}
68		line[HEXDUMP_LINELEN] = 0x0;
69		o += snprintf(&out[o], size - o, " | %s\n", line);
70	}
71	return (ssize_t)o;
72}
73
74void dumpmem(void */*p*/, size_t /*size*/);
75
76/* just dump an area of memory to stdout */
77void
78dumpmem(void *vp, size_t size)
79{
80	ssize_t	cc;
81	uint8_t	*p = (uint8_t *)vp;
82	char	*buf;
83
84	buf = calloc(1, size * 5);
85	cc = hexdump((const char *)p, size, buf, size * 5);
86	fprintf(stdout, "%.*s\n", (int)cc, buf);
87	free(buf);
88}
89