1 // Copyright 2016 The Fuchsia Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include <pretty/hexdump.h>
6 
7 #include <ctype.h>
8 #include <inttypes.h>
9 #include <stdint.h>
10 #include <stdio.h>
11 
12 #define ROUNDUP(a, b) (((a) + ((b)-1)) & ~((b)-1))
13 #define MIN(a, b) (((a) < (b)) ? (a) : (b))
14 
hexdump_ex(const void * ptr,size_t len,uint64_t disp_addr)15 void hexdump_ex(const void* ptr, size_t len, uint64_t disp_addr) {
16     uintptr_t address = (uintptr_t)ptr;
17     size_t count;
18 
19     for (count = 0; count < len; count += 16) {
20         union {
21             uint32_t buf[4];
22             uint8_t cbuf[16];
23         } u;
24         size_t s = ROUNDUP(MIN(len - count, 16), 4);
25         size_t i;
26 
27         printf(((disp_addr + len) > 0xFFFFFFFF)
28                    ? "0x%016" PRIx64 ": "
29                    : "0x%08" PRIx64 ": ",
30                disp_addr + count);
31 
32         for (i = 0; i < s / 4; i++) {
33             u.buf[i] = ((const uint32_t*)address)[i];
34             printf("%08x ", u.buf[i]);
35         }
36         for (; i < 4; i++) {
37             printf("         ");
38         }
39         printf("|");
40 
41         for (i = 0; i < 16; i++) {
42             char c = u.cbuf[i];
43             if (i < s && isprint(c)) {
44                 printf("%c", c);
45             } else {
46                 printf(".");
47             }
48         }
49         printf("|\n");
50         address += 16;
51     }
52 }
53 
hexdump8_ex(const void * ptr,size_t len,uint64_t disp_addr)54 void hexdump8_ex(const void* ptr, size_t len, uint64_t disp_addr) {
55     uintptr_t address = (uintptr_t)ptr;
56     size_t count;
57     size_t i;
58 
59     for (count = 0; count < len; count += 16) {
60         printf(((disp_addr + len) > 0xFFFFFFFF)
61                    ? "0x%016" PRIx64 ": "
62                    : "0x%08" PRIx64 ": ",
63                disp_addr + count);
64 
65         for (i = 0; i < MIN(len - count, 16); i++) {
66             printf("%02hhx ", *(const uint8_t*)(address + i));
67         }
68 
69         for (; i < 16; i++) {
70             printf("   ");
71         }
72 
73         printf("|");
74 
75         for (i = 0; i < MIN(len - count, 16); i++) {
76             char c = ((const char*)address)[i];
77             printf("%c", isprint(c) ? c : '.');
78         }
79 
80         printf("\n");
81         address += 16;
82     }
83 }
84