]>
Commit | Line | Data |
---|---|---|
031e5cce SM |
1 | // SPDX-License-Identifier: BSD-2-Clause-Patent |
2 | ||
db90de78 PJ |
3 | #ifndef STATIC_HEXDUMP_H |
4 | #define STATIC_HEXDUMP_H | |
5 | ||
031e5cce SM |
6 | #include "shim.h" |
7 | #include "include/console.h" | |
db90de78 | 8 | |
031e5cce SM |
9 | static inline unsigned long UNUSED |
10 | prepare_hex(const void *data, size_t size, char *buf, unsigned int position) | |
db90de78 | 11 | { |
031e5cce | 12 | char hexchars[] = "0123456789abcdef"; |
db90de78 | 13 | int offset = 0; |
031e5cce SM |
14 | unsigned long i; |
15 | unsigned long j; | |
16 | unsigned long ret; | |
db90de78 | 17 | |
031e5cce SM |
18 | unsigned long before = (position % 16); |
19 | unsigned long after = (before+size >= 16) ? 0 : 16 - (before+size); | |
20 | ||
21 | for (i = 0; i < before; i++) { | |
22 | buf[offset++] = 'X'; | |
23 | buf[offset++] = 'X'; | |
24 | buf[offset++] = ' '; | |
db90de78 | 25 | if (i == 7) |
031e5cce | 26 | buf[offset++] = ' '; |
db90de78 | 27 | } |
031e5cce SM |
28 | for (j = 0; j < 16 - after - before; j++) { |
29 | uint8_t d = ((uint8_t *)data)[j]; | |
db90de78 PJ |
30 | buf[offset++] = hexchars[(d & 0xf0) >> 4]; |
31 | buf[offset++] = hexchars[(d & 0x0f)]; | |
031e5cce SM |
32 | if (i+j != 15) |
33 | buf[offset++] = ' '; | |
34 | if (i+j == 7) | |
35 | buf[offset++] = ' '; | |
db90de78 | 36 | } |
031e5cce SM |
37 | ret = 16 - after - before; |
38 | j += i; | |
39 | for (i = 0; i < after; i++) { | |
40 | buf[offset++] = 'X'; | |
41 | buf[offset++] = 'X'; | |
42 | if (i+j != 15) | |
43 | buf[offset++] = ' '; | |
44 | if (i+j == 7) | |
45 | buf[offset++] = ' '; | |
db90de78 | 46 | } |
031e5cce SM |
47 | buf[offset] = '\0'; |
48 | return ret; | |
db90de78 PJ |
49 | } |
50 | ||
031e5cce SM |
51 | static inline void UNUSED |
52 | prepare_text(const void *data, size_t size, char *buf, unsigned int position) | |
db90de78 | 53 | { |
db90de78 | 54 | int offset = 0; |
031e5cce SM |
55 | unsigned long i; |
56 | unsigned long j; | |
57 | ||
58 | unsigned long before = position % 16; | |
59 | unsigned long after = (before+size > 16) ? 0 : 16 - (before+size); | |
60 | ||
61 | if (size == 0) { | |
62 | buf[0] = '\0'; | |
63 | return; | |
64 | } | |
65 | for (i = 0; i < before; i++) | |
66 | buf[offset++] = 'X'; | |
67 | buf[offset++] = '|'; | |
68 | for (j = 0; j < 16 - after - before; j++) { | |
69 | if (isprint(((uint8_t *)data)[j])) | |
70 | buf[offset++] = ((uint8_t *)data)[j]; | |
db90de78 | 71 | else |
031e5cce | 72 | buf[offset++] = '.'; |
db90de78 | 73 | } |
8529e0f7 | 74 | buf[offset++] = '|'; |
031e5cce | 75 | buf[offset] = '\0'; |
db90de78 PJ |
76 | } |
77 | ||
031e5cce SM |
78 | /* |
79 | * variadic hexdump formatted | |
80 | * think of it as: printf("%s%s\n", vformat(fmt, ap), hexdump(data,size)); | |
81 | */ | |
82 | static inline void UNUSED EFIAPI | |
83 | vhexdumpf(const char *file, int line, const char *func, const CHAR16 *const fmt, | |
84 | const void *data, unsigned long size, size_t at, ms_va_list ap) | |
db90de78 | 85 | { |
031e5cce SM |
86 | unsigned long display_offset = at; |
87 | unsigned long offset = 0; | |
88 | ||
89 | if (verbose == 0) | |
90 | return; | |
db90de78 | 91 | |
8529e0f7 SM |
92 | if (!data || !size) { |
93 | dprint(L"hexdump of a NULL pointer!\n"); | |
94 | return; | |
95 | } | |
96 | ||
db90de78 | 97 | while (offset < size) { |
031e5cce SM |
98 | char hexbuf[49]; |
99 | char txtbuf[19]; | |
100 | unsigned long sz; | |
db90de78 | 101 | |
031e5cce SM |
102 | sz = prepare_hex(data+offset, size-offset, hexbuf, |
103 | (unsigned long)data+offset); | |
db90de78 PJ |
104 | if (sz == 0) |
105 | return; | |
db90de78 | 106 | |
031e5cce SM |
107 | prepare_text(data+offset, size-offset, txtbuf, |
108 | (unsigned long)data+offset); | |
109 | if (fmt && fmt[0] != 0) | |
110 | vdprint_(fmt, file, line, func, ap); | |
111 | dprint_(L"%a:%d:%a() %08lx %a %a\n", file, line, func, display_offset, hexbuf, txtbuf); | |
db90de78 PJ |
112 | |
113 | display_offset += sz; | |
114 | offset += sz; | |
115 | } | |
116 | } | |
117 | ||
031e5cce SM |
118 | /* |
119 | * hexdump formatted | |
120 | * think of it as: printf("%s%s", format(fmt, ...), hexdump(data,size)[lineN]); | |
121 | */ | |
122 | static inline void UNUSED EFIAPI | |
123 | hexdumpf(const char *file, int line, const char *func, const CHAR16 *const fmt, | |
124 | const void *data, unsigned long size, size_t at, ...) | |
125 | { | |
126 | ms_va_list ap; | |
127 | ||
128 | ms_va_start(ap, at); | |
129 | vhexdumpf(file, line, func, fmt, data, size, at, ap); | |
130 | ms_va_end(ap); | |
131 | } | |
132 | ||
133 | static inline void UNUSED | |
134 | hexdump(const char *file, int line, const char *func, const void *data, unsigned long size) | |
135 | { | |
136 | hexdumpf(file, line, func, L"", data, size, (intptr_t)data); | |
137 | } | |
138 | ||
139 | static inline void UNUSED | |
140 | hexdumpat(const char *file, int line, const char *func, const void *data, unsigned long size, size_t at) | |
141 | { | |
142 | hexdumpf(file, line, func, L"", data, size, at); | |
143 | } | |
144 | ||
8529e0f7 SM |
145 | #if defined(SHIM_UNIT_TEST) |
146 | #define LogHexDump(data, ...) | |
147 | #define dhexdump(data, ...) | |
148 | #define dhexdumpat(data, ...) | |
149 | #define dhexdumpf(fmt, ...) | |
150 | #else | |
031e5cce SM |
151 | #define LogHexdump(data, sz) LogHexdump_(__FILE__, __LINE__, __func__, data, sz) |
152 | #define dhexdump(data, sz) hexdump(__FILE__, __LINE__, __func__, data, sz) | |
153 | #define dhexdumpat(data, sz, at) \ | |
154 | hexdumpat(__FILE__, __LINE__ - 1, __func__, data, sz, at) | |
155 | #define dhexdumpf(fmt, data, sz, at, ...) \ | |
156 | hexdumpf(__FILE__, __LINE__ - 1, __func__, fmt, data, sz, at, ##__VA_ARGS__) | |
8529e0f7 | 157 | #endif |
031e5cce | 158 | |
f892ac66 | 159 | #endif /* STATIC_HEXDUMP_H */ |
031e5cce | 160 | // vim:fenc=utf-8:tw=75:noet |