diff options
Diffstat (limited to 'lib/hexdump.c')
-rw-r--r-- | lib/hexdump.c | 72 |
1 files changed, 55 insertions, 17 deletions
diff --git a/lib/hexdump.c b/lib/hexdump.c index 39af2560f765..f5fe6ba7a3ab 100644 --- a/lib/hexdump.c +++ b/lib/hexdump.c | |||
@@ -16,6 +16,40 @@ const char hex_asc[] = "0123456789abcdef"; | |||
16 | EXPORT_SYMBOL(hex_asc); | 16 | EXPORT_SYMBOL(hex_asc); |
17 | 17 | ||
18 | /** | 18 | /** |
19 | * hex_to_bin - convert a hex digit to its real value | ||
20 | * @ch: ascii character represents hex digit | ||
21 | * | ||
22 | * hex_to_bin() converts one hex digit to its actual value or -1 in case of bad | ||
23 | * input. | ||
24 | */ | ||
25 | int hex_to_bin(char ch) | ||
26 | { | ||
27 | if ((ch >= '0') && (ch <= '9')) | ||
28 | return ch - '0'; | ||
29 | ch = tolower(ch); | ||
30 | if ((ch >= 'a') && (ch <= 'f')) | ||
31 | return ch - 'a' + 10; | ||
32 | return -1; | ||
33 | } | ||
34 | EXPORT_SYMBOL(hex_to_bin); | ||
35 | |||
36 | /** | ||
37 | * hex2bin - convert an ascii hexadecimal string to its binary representation | ||
38 | * @dst: binary result | ||
39 | * @src: ascii hexadecimal string | ||
40 | * @count: result length | ||
41 | */ | ||
42 | void hex2bin(u8 *dst, const char *src, size_t count) | ||
43 | { | ||
44 | while (count--) { | ||
45 | *dst = hex_to_bin(*src++) << 4; | ||
46 | *dst += hex_to_bin(*src++); | ||
47 | dst++; | ||
48 | } | ||
49 | } | ||
50 | EXPORT_SYMBOL(hex2bin); | ||
51 | |||
52 | /** | ||
19 | * hex_dump_to_buffer - convert a blob of data to "hex ASCII" in memory | 53 | * hex_dump_to_buffer - convert a blob of data to "hex ASCII" in memory |
20 | * @buf: data blob to dump | 54 | * @buf: data blob to dump |
21 | * @len: number of bytes in the @buf | 55 | * @len: number of bytes in the @buf |
@@ -34,7 +68,7 @@ EXPORT_SYMBOL(hex_asc); | |||
34 | * | 68 | * |
35 | * E.g.: | 69 | * E.g.: |
36 | * hex_dump_to_buffer(frame->data, frame->len, 16, 1, | 70 | * hex_dump_to_buffer(frame->data, frame->len, 16, 1, |
37 | * linebuf, sizeof(linebuf), 1); | 71 | * linebuf, sizeof(linebuf), true); |
38 | * | 72 | * |
39 | * example output buffer: | 73 | * example output buffer: |
40 | * 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f @ABCDEFGHIJKLMNO | 74 | * 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f @ABCDEFGHIJKLMNO |
@@ -65,8 +99,8 @@ void hex_dump_to_buffer(const void *buf, size_t len, int rowsize, | |||
65 | 99 | ||
66 | for (j = 0; j < ngroups; j++) | 100 | for (j = 0; j < ngroups; j++) |
67 | lx += scnprintf(linebuf + lx, linebuflen - lx, | 101 | lx += scnprintf(linebuf + lx, linebuflen - lx, |
68 | "%s%16.16llx", j ? " " : "", | 102 | "%s%16.16llx", j ? " " : "", |
69 | (unsigned long long)*(ptr8 + j)); | 103 | (unsigned long long)*(ptr8 + j)); |
70 | ascii_column = 17 * ngroups + 2; | 104 | ascii_column = 17 * ngroups + 2; |
71 | break; | 105 | break; |
72 | } | 106 | } |
@@ -77,7 +111,7 @@ void hex_dump_to_buffer(const void *buf, size_t len, int rowsize, | |||
77 | 111 | ||
78 | for (j = 0; j < ngroups; j++) | 112 | for (j = 0; j < ngroups; j++) |
79 | lx += scnprintf(linebuf + lx, linebuflen - lx, | 113 | lx += scnprintf(linebuf + lx, linebuflen - lx, |
80 | "%s%8.8x", j ? " " : "", *(ptr4 + j)); | 114 | "%s%8.8x", j ? " " : "", *(ptr4 + j)); |
81 | ascii_column = 9 * ngroups + 2; | 115 | ascii_column = 9 * ngroups + 2; |
82 | break; | 116 | break; |
83 | } | 117 | } |
@@ -88,7 +122,7 @@ void hex_dump_to_buffer(const void *buf, size_t len, int rowsize, | |||
88 | 122 | ||
89 | for (j = 0; j < ngroups; j++) | 123 | for (j = 0; j < ngroups; j++) |
90 | lx += scnprintf(linebuf + lx, linebuflen - lx, | 124 | lx += scnprintf(linebuf + lx, linebuflen - lx, |
91 | "%s%4.4x", j ? " " : "", *(ptr2 + j)); | 125 | "%s%4.4x", j ? " " : "", *(ptr2 + j)); |
92 | ascii_column = 5 * ngroups + 2; | 126 | ascii_column = 5 * ngroups + 2; |
93 | break; | 127 | break; |
94 | } | 128 | } |
@@ -111,14 +145,16 @@ void hex_dump_to_buffer(const void *buf, size_t len, int rowsize, | |||
111 | 145 | ||
112 | while (lx < (linebuflen - 1) && lx < (ascii_column - 1)) | 146 | while (lx < (linebuflen - 1) && lx < (ascii_column - 1)) |
113 | linebuf[lx++] = ' '; | 147 | linebuf[lx++] = ' '; |
114 | for (j = 0; (j < len) && (lx + 2) < linebuflen; j++) | 148 | for (j = 0; (j < len) && (lx + 2) < linebuflen; j++) { |
115 | linebuf[lx++] = (isascii(ptr[j]) && isprint(ptr[j])) ? ptr[j] | 149 | ch = ptr[j]; |
116 | : '.'; | 150 | linebuf[lx++] = (isascii(ch) && isprint(ch)) ? ch : '.'; |
151 | } | ||
117 | nil: | 152 | nil: |
118 | linebuf[lx++] = '\0'; | 153 | linebuf[lx++] = '\0'; |
119 | } | 154 | } |
120 | EXPORT_SYMBOL(hex_dump_to_buffer); | 155 | EXPORT_SYMBOL(hex_dump_to_buffer); |
121 | 156 | ||
157 | #ifdef CONFIG_PRINTK | ||
122 | /** | 158 | /** |
123 | * print_hex_dump - print a text hex dump to syslog for a binary blob of data | 159 | * print_hex_dump - print a text hex dump to syslog for a binary blob of data |
124 | * @level: kernel log level (e.g. KERN_DEBUG) | 160 | * @level: kernel log level (e.g. KERN_DEBUG) |
@@ -143,7 +179,7 @@ EXPORT_SYMBOL(hex_dump_to_buffer); | |||
143 | * | 179 | * |
144 | * E.g.: | 180 | * E.g.: |
145 | * print_hex_dump(KERN_DEBUG, "raw data: ", DUMP_PREFIX_ADDRESS, | 181 | * print_hex_dump(KERN_DEBUG, "raw data: ", DUMP_PREFIX_ADDRESS, |
146 | * 16, 1, frame->data, frame->len, 1); | 182 | * 16, 1, frame->data, frame->len, true); |
147 | * | 183 | * |
148 | * Example output using %DUMP_PREFIX_OFFSET and 1-byte mode: | 184 | * Example output using %DUMP_PREFIX_OFFSET and 1-byte mode: |
149 | * 0009ab42: 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f @ABCDEFGHIJKLMNO | 185 | * 0009ab42: 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f @ABCDEFGHIJKLMNO |
@@ -151,12 +187,12 @@ EXPORT_SYMBOL(hex_dump_to_buffer); | |||
151 | * ffffffff88089af0: 73727170 77767574 7b7a7978 7f7e7d7c pqrstuvwxyz{|}~. | 187 | * ffffffff88089af0: 73727170 77767574 7b7a7978 7f7e7d7c pqrstuvwxyz{|}~. |
152 | */ | 188 | */ |
153 | void print_hex_dump(const char *level, const char *prefix_str, int prefix_type, | 189 | void print_hex_dump(const char *level, const char *prefix_str, int prefix_type, |
154 | int rowsize, int groupsize, | 190 | int rowsize, int groupsize, |
155 | const void *buf, size_t len, bool ascii) | 191 | const void *buf, size_t len, bool ascii) |
156 | { | 192 | { |
157 | const u8 *ptr = buf; | 193 | const u8 *ptr = buf; |
158 | int i, linelen, remaining = len; | 194 | int i, linelen, remaining = len; |
159 | unsigned char linebuf[200]; | 195 | unsigned char linebuf[32 * 3 + 2 + 32 + 1]; |
160 | 196 | ||
161 | if (rowsize != 16 && rowsize != 32) | 197 | if (rowsize != 16 && rowsize != 32) |
162 | rowsize = 16; | 198 | rowsize = 16; |
@@ -164,13 +200,14 @@ void print_hex_dump(const char *level, const char *prefix_str, int prefix_type, | |||
164 | for (i = 0; i < len; i += rowsize) { | 200 | for (i = 0; i < len; i += rowsize) { |
165 | linelen = min(remaining, rowsize); | 201 | linelen = min(remaining, rowsize); |
166 | remaining -= rowsize; | 202 | remaining -= rowsize; |
203 | |||
167 | hex_dump_to_buffer(ptr + i, linelen, rowsize, groupsize, | 204 | hex_dump_to_buffer(ptr + i, linelen, rowsize, groupsize, |
168 | linebuf, sizeof(linebuf), ascii); | 205 | linebuf, sizeof(linebuf), ascii); |
169 | 206 | ||
170 | switch (prefix_type) { | 207 | switch (prefix_type) { |
171 | case DUMP_PREFIX_ADDRESS: | 208 | case DUMP_PREFIX_ADDRESS: |
172 | printk("%s%s%*p: %s\n", level, prefix_str, | 209 | printk("%s%s%p: %s\n", |
173 | (int)(2 * sizeof(void *)), ptr + i, linebuf); | 210 | level, prefix_str, ptr + i, linebuf); |
174 | break; | 211 | break; |
175 | case DUMP_PREFIX_OFFSET: | 212 | case DUMP_PREFIX_OFFSET: |
176 | printk("%s%s%.8x: %s\n", level, prefix_str, i, linebuf); | 213 | printk("%s%s%.8x: %s\n", level, prefix_str, i, linebuf); |
@@ -196,9 +233,10 @@ EXPORT_SYMBOL(print_hex_dump); | |||
196 | * rowsize of 16, groupsize of 1, and ASCII output included. | 233 | * rowsize of 16, groupsize of 1, and ASCII output included. |
197 | */ | 234 | */ |
198 | void print_hex_dump_bytes(const char *prefix_str, int prefix_type, | 235 | void print_hex_dump_bytes(const char *prefix_str, int prefix_type, |
199 | const void *buf, size_t len) | 236 | const void *buf, size_t len) |
200 | { | 237 | { |
201 | print_hex_dump(KERN_DEBUG, prefix_str, prefix_type, 16, 1, | 238 | print_hex_dump(KERN_DEBUG, prefix_str, prefix_type, 16, 1, |
202 | buf, len, 1); | 239 | buf, len, true); |
203 | } | 240 | } |
204 | EXPORT_SYMBOL(print_hex_dump_bytes); | 241 | EXPORT_SYMBOL(print_hex_dump_bytes); |
242 | #endif | ||