1 /*- 2 * Copyright (c) 2012 Alistair Crooks <agc@NetBSD.org> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 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 */ 42 static ssize_t 43 hexdump(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 74 void dumpmem(void */*p*/, size_t /*size*/); 75 76 /* just dump an area of memory to stdout */ 77 void 78 dumpmem(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