linuxkpi: Add hex_dump_to_buffer()

This function prints a single line of hex dump to the given line buffer.

The implementation relies on `lkpi_hex_dump()` to format the string.

Reviewed by:	bz
Sponsored by:	The FreeBSD Foundation
Differential Revision: https://reviews.freebsd.org/D51559
This commit is contained in:
Jean-Sébastien Pédron
2025-07-11 01:03:51 +02:00
parent 43b5a264c6
commit b1bef9f7e0
2 changed files with 76 additions and 0 deletions
@@ -50,6 +50,12 @@ void lkpi_hex_dump(int(*)(void *, const char *, ...), void *arg1,
const char *, const char *, const int, const int, const int,
const void *, size_t, const bool, const bool);
#define hex_dump_to_buffer(buf, len, rowsize, groupsize, linebuf, linebuflen, ascii) \
lkpi_hex_dump_to_buffer((buf), (len), (rowsize), (groupsize), (linebuf), (linebuflen), (ascii))
int lkpi_hex_dump_to_buffer(const void *buf, size_t len, int rowsize,
int groupsize, char *linebuf, size_t linebuflen, bool ascii);
static inline void
print_hex_dump(const char *level, const char *prefix_str,
const int prefix_type, const int rowsize, const int groupsize,
@@ -1986,6 +1986,76 @@ lkpi_hex_dump(int(*_fpf)(void *, const char *, ...), void *arg1,
}
}
struct hdtb_context {
char *linebuf;
size_t linebuflen;
int written;
};
static int
hdtb_cb(void *arg, const char *format, ...)
{
struct hdtb_context *context;
int written;
va_list args;
context = arg;
va_start(args, format);
written = vsnprintf(
context->linebuf, context->linebuflen, format, args);
va_end(args);
if (written < 0)
return (written);
/*
* Linux' hex_dump_to_buffer() function has the same behaviour as
* snprintf() basically. Therefore, it returns the number of bytes it
* would have written if the destination buffer was large enough.
*
* If the destination buffer was exhausted, lkpi_hex_dump() will
* continue to call this callback but it will only compute the bytes it
* would have written but write nothing to that buffer.
*/
context->written += written;
if (written < context->linebuflen) {
context->linebuf += written;
context->linebuflen -= written;
} else {
context->linebuf += context->linebuflen;
context->linebuflen = 0;
}
return (written);
}
int
lkpi_hex_dump_to_buffer(const void *buf, size_t len, int rowsize,
int groupsize, char *linebuf, size_t linebuflen, bool ascii)
{
int written;
struct hdtb_context context;
context.linebuf = linebuf;
context.linebuflen = linebuflen;
context.written = 0;
if (rowsize != 16 && rowsize != 32)
rowsize = 16;
len = min(len, rowsize);
lkpi_hex_dump(
hdtb_cb, &context, NULL, NULL, DUMP_PREFIX_NONE,
rowsize, groupsize, buf, len, ascii, false);
written = context.written;
return (written);
}
static void
linux_timer_callback_wrapper(void *context)
{