1 /* 2 * This file and its contents are supplied under the terms of the 3 * Common Development and Distribution License ("CDDL"), version 1.0. 4 * You may only use this file in accordance with the terms of version 5 * 1.0 of the CDDL. 6 * 7 * A full copy of the text of the CDDL should have accompanied this 8 * source. A copy of the CDDL is also available via the Internet at 9 * http://www.illumos.org/license/CDDL. 10 */ 11 12 /* 13 * Copyright 2024 Oxide Computer Company 14 */ 15 16 #ifndef _HEXDUMP_H_ 17 #define _HEXDUMP_H_ 18 19 /* 20 * Header file for the generic hexdump implementation in 21 * common/hexdump/hexdump.c 22 */ 23 24 #include <sys/types.h> 25 26 #ifndef _KERNEL 27 #include <stdio.h> 28 #endif 29 30 #ifdef __cplusplus 31 extern "C" { 32 #endif 33 34 typedef enum { 35 /* 36 * Include a header row showing byte positions. 37 */ 38 HDF_HEADER = 1 << 0, 39 /* 40 * Include the address of the first byte for each row at the left. 41 */ 42 HDF_ADDRESS = 1 << 1, 43 /* 44 * Include an ASCII table at the right hand side with unprintable bytes 45 * displayed as '.'. 46 */ 47 HDF_ASCII = 1 << 2, 48 /* 49 * If the data is not naturally aligned to the paragraph size, start 50 * the table from an aligned address and indicate where the data starts 51 * with a marker in the table header (if enabled). Missing data are 52 * shown with space characters. 53 */ 54 HDF_ALIGN = 1 << 3, 55 /* 56 * Suppress duplicate lines in the output, replacing them with a single 57 * "*". 58 */ 59 HDF_DEDUP = 1 << 4, 60 /* 61 * When laying out byte columns, use two spaces instead of one. This 62 * results in the data being more spread out and easier to read in some 63 * circumstances. 64 */ 65 HDF_DOUBLESPACE = 1 << 5, 66 } hexdump_flag_t; 67 68 /* 69 * Most consumers of the hexdump routines should use this default set of flags 70 * so we have consistent output across the gate. 71 */ 72 #define HDF_DEFAULT (HDF_HEADER | HDF_ADDRESS | HDF_ASCII) 73 74 /* 75 * Consumers of this code should treat this as an opaque type and initialise it 76 * with a call to hexdump_init(). It is defined here so that it can be placed 77 * on the stack which is particularly useful during early boot, before the kmem 78 * system is ready. 79 */ 80 typedef struct { 81 uint64_t h_addr; /* display address */ 82 uint8_t h_width; /* bytes per row */ 83 uint8_t h_grouping; /* display bytes in groups of.. */ 84 uint8_t h_indent; /* Left indent */ 85 uint8_t h_marker; /* marker offset */ 86 uint8_t *h_buf; /* optional pre-allocated buffer... */ 87 size_t h_buflen; /* ...and its size */ 88 } hexdump_t; 89 90 /* 91 * Initialise and finalise a hexdump_t. 92 */ 93 extern void hexdump_init(hexdump_t *); 94 extern void hexdump_fini(hexdump_t *); 95 96 /* 97 * Set the start address that corresponds to the provided data. This is used to 98 * display addresses in conjunction with the HDF_ADDRESS option. 99 */ 100 extern void hexdump_set_addr(hexdump_t *, uint64_t); 101 102 /* 103 * Select the number of bytes per line. The default is 16. 104 */ 105 extern void hexdump_set_width(hexdump_t *, uint8_t); 106 107 /* 108 * Group bytes together. The default grouping is 1 which results in each byte 109 * being displayed surrounded by space. As a readability improvement an extra 110 * space is added after every 8 bytes when using a grouping of 1. 111 */ 112 extern void hexdump_set_grouping(hexdump_t *, uint8_t); 113 114 /* 115 * Set a number of spaces that should precede each row as an indent. 116 */ 117 extern void hexdump_set_indent(hexdump_t *, uint8_t); 118 119 /* 120 * Set a marker in the header for the start of interesting data. This will only 121 * be displayed if the header is enabled with the HDF_HEADER option, and if the 122 * marker value is less than the configured row width. 123 */ 124 extern void hexdump_set_marker(hexdump_t *, uint8_t); 125 126 /* 127 * Provide a scratch space working buffer. This is necessary in early boot, 128 * before kmem is ready. 129 */ 130 extern void hexdump_set_buf(hexdump_t *, uint8_t *, size_t); 131 132 /* 133 * The hexdump() function that does the work. It takes the following arguments: 134 * 135 * const uint8_t *addr - a pointer to the data to be dumped 136 * size_t len - the length of the data 137 * hexdump_flag_t flags - flags as per the definitions above 138 * hexdump_cb_f callback - fucntion called for each table row 139 * void *callback_arg - pointer passed to callback function 140 * 141 * More customisation can be achieved by using hexdumph() which takes an 142 * additional hexdump_t *. 143 */ 144 typedef int (*hexdump_cb_f)(void *, uint64_t, const char *, size_t); 145 extern int hexdump(const uint8_t *, size_t, hexdump_flag_t, 146 hexdump_cb_f, void *); 147 148 /* 149 * A version that takes a hexdump_t allowing for more customisation. 150 */ 151 extern int hexdumph(hexdump_t *, const uint8_t *, size_t, hexdump_flag_t, 152 hexdump_cb_f, void *); 153 154 #ifndef _KERNEL 155 /* 156 * Convenience wrappers in non-kernel context that output each table row to 157 * the provided FILE *. 158 */ 159 extern int hexdump_file(const uint8_t *, size_t, hexdump_flag_t, FILE *); 160 extern int hexdump_fileh(hexdump_t *, const uint8_t *, size_t, hexdump_flag_t, 161 FILE *); 162 #endif /* _KERNEL */ 163 164 #ifdef __cplusplus 165 } 166 #endif 167 168 #endif /* _HEXDUMP_H_ */ 169