1/* SPDX-License-Identifier: GPL-2.0+ */ 2/* 3 * Copyright (C) 2018 Synopsys, Inc. All rights reserved. 4 * 5 */ 6 7#ifndef HEXDUMP_H 8#define HEXDUMP_H 9 10#include <linux/ctype.h> 11#include <linux/types.h> 12 13enum dump_prefix_t { 14 DUMP_PREFIX_NONE, 15 DUMP_PREFIX_ADDRESS, 16 DUMP_PREFIX_OFFSET 17}; 18 19extern const char hex_asc[]; 20#define hex_asc_lo(x) hex_asc[((x) & 0x0f)] 21#define hex_asc_hi(x) hex_asc[((x) & 0xf0) >> 4] 22 23static inline char *hex_byte_pack(char *buf, u8 byte) 24{ 25 *buf++ = hex_asc_hi(byte); 26 *buf++ = hex_asc_lo(byte); 27 return buf; 28} 29 30/** 31 * hex_to_bin - convert a hex digit to its real value 32 * @ch: ascii character represents hex digit 33 * 34 * hex_to_bin() converts one hex digit to its actual value or -1 in case of bad 35 * input. 36 */ 37static inline int hex_to_bin(char ch) 38{ 39 if ((ch >= '0') && (ch <= '9')) 40 return ch - '0'; 41 ch = tolower(ch); 42 if ((ch >= 'a') && (ch <= 'f')) 43 return ch - 'a' + 10; 44 return -1; 45} 46 47/** 48 * hex2bin - convert an ascii hexadecimal string to its binary representation 49 * @dst: binary result 50 * @src: ascii hexadecimal string 51 * @count: result length 52 * 53 * Return 0 on success, -1 in case of bad input. 54 */ 55static inline int hex2bin(u8 *dst, const char *src, size_t count) 56{ 57 while (count--) { 58 int hi = hex_to_bin(*src++); 59 int lo = hex_to_bin(*src++); 60 61 if ((hi < 0) || (lo < 0)) 62 return -1; 63 64 *dst++ = (hi << 4) | lo; 65 } 66 return 0; 67} 68 69/** 70 * bin2hex - convert binary data to an ascii hexadecimal string 71 * @dst: ascii hexadecimal result 72 * @src: binary data 73 * @count: binary data length 74 */ 75static inline char *bin2hex(char *dst, const void *src, size_t count) 76{ 77 const unsigned char *_src = src; 78 79 while (count--) 80 dst = hex_byte_pack(dst, *_src++); 81 return dst; 82} 83 84/** 85 * hex_dump_to_buffer - convert a blob of data to "hex ASCII" in memory 86 * @buf: data blob to dump 87 * @len: number of bytes in the @buf 88 * @rowsize: number of bytes to print per line; max 64 89 * @groupsize: number of bytes to print at a time (1, 2, 4, 8; default = 1) 90 * @linebuf: where to put the converted data 91 * @linebuflen: total size of @linebuf, including space for terminating NUL 92 * @ascii: include ASCII after the hex output 93 * 94 * hex_dump_to_buffer() works on one "line" of output at a time, i.e., 95 * 16 or 32 bytes of input data converted to hex + ASCII output. 96 * 97 * Given a buffer of u8 data, hex_dump_to_buffer() converts the input data 98 * to a hex + ASCII dump at the supplied memory location. 99 * The converted output is always NUL-terminated. 100 * 101 * E.g.: 102 * hex_dump_to_buffer(frame->data, frame->len, 16, 1, 103 * linebuf, sizeof(linebuf), true); 104 * 105 * example output buffer: 106 * 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f @ABCDEFGHIJKLMNO 107 * 108 * Return: 109 * The amount of bytes placed in the buffer without terminating NUL. If the 110 * output was truncated, then the return value is the number of bytes 111 * (excluding the terminating NUL) which would have been written to the final 112 * string if enough space had been available. 113 */ 114int hex_dump_to_buffer(const void *buf, size_t len, int rowsize, int groupsize, 115 char *linebuf, size_t linebuflen, bool ascii); 116 117/** 118 * print_hex_dump - print a text hex dump to syslog for a binary blob of data 119 * @prefix_str: string to prefix each line with; 120 * caller supplies trailing spaces for alignment if desired 121 * @prefix_type: controls whether prefix of an offset, address, or none 122 * is printed (see enum dump_prefix_t) 123 * @rowsize: number of bytes to print per line; max 64 124 * @groupsize: number of bytes to print at a time (1, 2, 4, 8; default = 1) 125 * @buf: data blob to dump 126 * @len: number of bytes in the @buf 127 * @ascii: include ASCII after the hex output 128 * Returns: 0 if finished normally, -EINTR if Ctrl-C was pressed, -ENOSYS if not 129 * supported 130 * 131 * Given a buffer of u8 data, print_hex_dump() prints a hex + ASCII dump 132 * to the stdio, with an optional leading prefix. 133 * 134 * print_hex_dump() works on one "line" of output at a time, i.e., 135 * 16 or 32 bytes of input data converted to hex + ASCII output. 136 * print_hex_dump() iterates over the entire input @buf, breaking it into 137 * "line size" chunks to format and print. 138 * 139 * E.g.: 140 * print_hex_dump("raw data: ", DUMP_PREFIX_ADDRESS, 16, 1, frame->data, 141 * frame->len, true); 142 * 143 * Example output using %DUMP_PREFIX_OFFSET and 1-byte mode: 144 * 0009ab42: 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f @ABCDEFGHIJKLMNO 145 * Example output using %DUMP_PREFIX_ADDRESS and 4-byte mode: 146 * ffffffff88089af0: 73727170 77767574 7b7a7978 7f7e7d7c pqrstuvwxyz{|}~. 147 */ 148int print_hex_dump(const char *prefix_str, int prefix_type, int rowsize, 149 int groupsize, const void *buf, size_t len, bool ascii); 150 151/** 152 * print_hex_dump_bytes - shorthand form of print_hex_dump() with default params 153 * @prefix_str: string to prefix each line with; 154 * caller supplies trailing spaces for alignment if desired 155 * @prefix_type: controls whether prefix of an offset, address, or none 156 * is printed (see enum dump_prefix_t) 157 * @buf: data blob to dump 158 * @len: number of bytes in the @buf 159 * 160 * Calls print_hex_dump(), rowsize of 16, groupsize of 1, 161 * and ASCII output included. 162 */ 163void print_hex_dump_bytes(const char *prefix_str, int prefix_type, 164 const void *buf, size_t len); 165 166#endif /* HEXDUMP_H */ 167