143379a28SAndy Fiddaman /* 243379a28SAndy Fiddaman * This file and its contents are supplied under the terms of the 343379a28SAndy Fiddaman * Common Development and Distribution License ("CDDL"), version 1.0. 443379a28SAndy Fiddaman * You may only use this file in accordance with the terms of version 543379a28SAndy Fiddaman * 1.0 of the CDDL. 643379a28SAndy Fiddaman * 743379a28SAndy Fiddaman * A full copy of the text of the CDDL should have accompanied this 843379a28SAndy Fiddaman * source. A copy of the CDDL is also available via the Internet at 943379a28SAndy Fiddaman * http://www.illumos.org/license/CDDL. 1043379a28SAndy Fiddaman */ 1143379a28SAndy Fiddaman 1243379a28SAndy Fiddaman /* 1343379a28SAndy Fiddaman * Copyright 2024 Oxide Computer Company 1443379a28SAndy Fiddaman */ 1543379a28SAndy Fiddaman 1643379a28SAndy Fiddaman #ifndef _HEXDUMP_H_ 1743379a28SAndy Fiddaman #define _HEXDUMP_H_ 1843379a28SAndy Fiddaman 1943379a28SAndy Fiddaman /* 2043379a28SAndy Fiddaman * Header file for the generic hexdump implementation in 2143379a28SAndy Fiddaman * common/hexdump/hexdump.c 2243379a28SAndy Fiddaman */ 2343379a28SAndy Fiddaman 2443379a28SAndy Fiddaman #include <sys/types.h> 2543379a28SAndy Fiddaman 2643379a28SAndy Fiddaman #ifndef _KERNEL 2743379a28SAndy Fiddaman #include <stdio.h> 2843379a28SAndy Fiddaman #endif 2943379a28SAndy Fiddaman 3043379a28SAndy Fiddaman #ifdef __cplusplus 3143379a28SAndy Fiddaman extern "C" { 3243379a28SAndy Fiddaman #endif 3343379a28SAndy Fiddaman 3443379a28SAndy Fiddaman typedef enum { 3543379a28SAndy Fiddaman /* 3643379a28SAndy Fiddaman * Include a header row showing byte positions. 3743379a28SAndy Fiddaman */ 3843379a28SAndy Fiddaman HDF_HEADER = 1 << 0, 3943379a28SAndy Fiddaman /* 4043379a28SAndy Fiddaman * Include the address of the first byte for each row at the left. 4143379a28SAndy Fiddaman */ 4243379a28SAndy Fiddaman HDF_ADDRESS = 1 << 1, 4343379a28SAndy Fiddaman /* 4443379a28SAndy Fiddaman * Include an ASCII table at the right hand side with unprintable bytes 4543379a28SAndy Fiddaman * displayed as '.'. 4643379a28SAndy Fiddaman */ 4743379a28SAndy Fiddaman HDF_ASCII = 1 << 2, 4843379a28SAndy Fiddaman /* 4943379a28SAndy Fiddaman * If the data is not naturally aligned to the paragraph size, start 5043379a28SAndy Fiddaman * the table from an aligned address and indicate where the data starts 5143379a28SAndy Fiddaman * with a marker in the table header (if enabled). Missing data are 5243379a28SAndy Fiddaman * shown with space characters. 5343379a28SAndy Fiddaman */ 5443379a28SAndy Fiddaman HDF_ALIGN = 1 << 3, 5543379a28SAndy Fiddaman /* 5643379a28SAndy Fiddaman * Suppress duplicate lines in the output, replacing them with a single 5743379a28SAndy Fiddaman * "*". 5843379a28SAndy Fiddaman */ 5943379a28SAndy Fiddaman HDF_DEDUP = 1 << 4, 6043379a28SAndy Fiddaman /* 6143379a28SAndy Fiddaman * When laying out byte columns, use two spaces instead of one. This 6243379a28SAndy Fiddaman * results in the data being more spread out and easier to read in some 6343379a28SAndy Fiddaman * circumstances. 6443379a28SAndy Fiddaman */ 6543379a28SAndy Fiddaman HDF_DOUBLESPACE = 1 << 5, 6643379a28SAndy Fiddaman } hexdump_flag_t; 6743379a28SAndy Fiddaman 6843379a28SAndy Fiddaman /* 6943379a28SAndy Fiddaman * Most consumers of the hexdump routines should use this default set of flags 7043379a28SAndy Fiddaman * so we have consistent output across the gate. 7143379a28SAndy Fiddaman */ 7243379a28SAndy Fiddaman #define HDF_DEFAULT (HDF_HEADER | HDF_ADDRESS | HDF_ASCII) 7343379a28SAndy Fiddaman 7443379a28SAndy Fiddaman /* 7543379a28SAndy Fiddaman * Consumers of this code should treat this as an opaque type and initialise it 7643379a28SAndy Fiddaman * with a call to hexdump_init(). It is defined here so that it can be placed 7743379a28SAndy Fiddaman * on the stack which is particularly useful during early boot, before the kmem 7843379a28SAndy Fiddaman * system is ready. 7943379a28SAndy Fiddaman */ 8043379a28SAndy Fiddaman typedef struct { 8143379a28SAndy Fiddaman uint64_t h_addr; /* display address */ 82*80b758daSAndy Fiddaman uint8_t h_addrwidth; /* Minimum address width */ 8343379a28SAndy Fiddaman uint8_t h_width; /* bytes per row */ 8443379a28SAndy Fiddaman uint8_t h_grouping; /* display bytes in groups of.. */ 8543379a28SAndy Fiddaman uint8_t h_indent; /* Left indent */ 8643379a28SAndy Fiddaman uint8_t h_marker; /* marker offset */ 8743379a28SAndy Fiddaman uint8_t *h_buf; /* optional pre-allocated buffer... */ 8843379a28SAndy Fiddaman size_t h_buflen; /* ...and its size */ 8943379a28SAndy Fiddaman } hexdump_t; 9043379a28SAndy Fiddaman 9143379a28SAndy Fiddaman /* 9243379a28SAndy Fiddaman * Initialise and finalise a hexdump_t. 9343379a28SAndy Fiddaman */ 9443379a28SAndy Fiddaman extern void hexdump_init(hexdump_t *); 9543379a28SAndy Fiddaman extern void hexdump_fini(hexdump_t *); 9643379a28SAndy Fiddaman 9743379a28SAndy Fiddaman /* 9843379a28SAndy Fiddaman * Set the start address that corresponds to the provided data. This is used to 9943379a28SAndy Fiddaman * display addresses in conjunction with the HDF_ADDRESS option. 10043379a28SAndy Fiddaman */ 10143379a28SAndy Fiddaman extern void hexdump_set_addr(hexdump_t *, uint64_t); 10243379a28SAndy Fiddaman 10343379a28SAndy Fiddaman /* 104*80b758daSAndy Fiddaman * Set a minimum width, in characters, for the addresses shown in conjunction 105*80b758daSAndy Fiddaman * with the HDF_ADDRESS option. The default behaviour is to calculate the width 106*80b758daSAndy Fiddaman * required to show all addresses and use that for all rows. 107*80b758daSAndy Fiddaman */ 108*80b758daSAndy Fiddaman extern void hexdump_set_addrwidth(hexdump_t *, uint8_t); 109*80b758daSAndy Fiddaman 110*80b758daSAndy Fiddaman /* 11143379a28SAndy Fiddaman * Select the number of bytes per line. The default is 16. 11243379a28SAndy Fiddaman */ 11343379a28SAndy Fiddaman extern void hexdump_set_width(hexdump_t *, uint8_t); 11443379a28SAndy Fiddaman 11543379a28SAndy Fiddaman /* 11643379a28SAndy Fiddaman * Group bytes together. The default grouping is 1 which results in each byte 11743379a28SAndy Fiddaman * being displayed surrounded by space. As a readability improvement an extra 11843379a28SAndy Fiddaman * space is added after every 8 bytes when using a grouping of 1. 11943379a28SAndy Fiddaman */ 12043379a28SAndy Fiddaman extern void hexdump_set_grouping(hexdump_t *, uint8_t); 12143379a28SAndy Fiddaman 12243379a28SAndy Fiddaman /* 12343379a28SAndy Fiddaman * Set a number of spaces that should precede each row as an indent. 12443379a28SAndy Fiddaman */ 12543379a28SAndy Fiddaman extern void hexdump_set_indent(hexdump_t *, uint8_t); 12643379a28SAndy Fiddaman 12743379a28SAndy Fiddaman /* 12843379a28SAndy Fiddaman * Set a marker in the header for the start of interesting data. This will only 12943379a28SAndy Fiddaman * be displayed if the header is enabled with the HDF_HEADER option, and if the 13043379a28SAndy Fiddaman * marker value is less than the configured row width. 13143379a28SAndy Fiddaman */ 13243379a28SAndy Fiddaman extern void hexdump_set_marker(hexdump_t *, uint8_t); 13343379a28SAndy Fiddaman 13443379a28SAndy Fiddaman /* 13543379a28SAndy Fiddaman * Provide a scratch space working buffer. This is necessary in early boot, 13643379a28SAndy Fiddaman * before kmem is ready. 13743379a28SAndy Fiddaman */ 13843379a28SAndy Fiddaman extern void hexdump_set_buf(hexdump_t *, uint8_t *, size_t); 13943379a28SAndy Fiddaman 14043379a28SAndy Fiddaman /* 14143379a28SAndy Fiddaman * The hexdump() function that does the work. It takes the following arguments: 14243379a28SAndy Fiddaman * 14343379a28SAndy Fiddaman * const uint8_t *addr - a pointer to the data to be dumped 14443379a28SAndy Fiddaman * size_t len - the length of the data 14543379a28SAndy Fiddaman * hexdump_flag_t flags - flags as per the definitions above 14643379a28SAndy Fiddaman * hexdump_cb_f callback - fucntion called for each table row 14743379a28SAndy Fiddaman * void *callback_arg - pointer passed to callback function 14843379a28SAndy Fiddaman * 14943379a28SAndy Fiddaman * More customisation can be achieved by using hexdumph() which takes an 15043379a28SAndy Fiddaman * additional hexdump_t *. 15143379a28SAndy Fiddaman */ 15243379a28SAndy Fiddaman typedef int (*hexdump_cb_f)(void *, uint64_t, const char *, size_t); 15343379a28SAndy Fiddaman extern int hexdump(const uint8_t *, size_t, hexdump_flag_t, 15443379a28SAndy Fiddaman hexdump_cb_f, void *); 15543379a28SAndy Fiddaman 15643379a28SAndy Fiddaman /* 15743379a28SAndy Fiddaman * A version that takes a hexdump_t allowing for more customisation. 15843379a28SAndy Fiddaman */ 15943379a28SAndy Fiddaman extern int hexdumph(hexdump_t *, const uint8_t *, size_t, hexdump_flag_t, 16043379a28SAndy Fiddaman hexdump_cb_f, void *); 16143379a28SAndy Fiddaman 16243379a28SAndy Fiddaman #ifndef _KERNEL 16343379a28SAndy Fiddaman /* 16443379a28SAndy Fiddaman * Convenience wrappers in non-kernel context that output each table row to 16543379a28SAndy Fiddaman * the provided FILE *. 16643379a28SAndy Fiddaman */ 16743379a28SAndy Fiddaman extern int hexdump_file(const uint8_t *, size_t, hexdump_flag_t, FILE *); 16843379a28SAndy Fiddaman extern int hexdump_fileh(hexdump_t *, const uint8_t *, size_t, hexdump_flag_t, 16943379a28SAndy Fiddaman FILE *); 17043379a28SAndy Fiddaman #endif /* _KERNEL */ 17143379a28SAndy Fiddaman 17243379a28SAndy Fiddaman #ifdef __cplusplus 17343379a28SAndy Fiddaman } 17443379a28SAndy Fiddaman #endif 17543379a28SAndy Fiddaman 17643379a28SAndy Fiddaman #endif /* _HEXDUMP_H_ */ 177