diff --git a/headers/private/kernel/debug_hex_dump.h b/headers/private/kernel/debug_hex_dump.h new file mode 100644 index 0000000000..7f042443c4 --- /dev/null +++ b/headers/private/kernel/debug_hex_dump.h @@ -0,0 +1,55 @@ +/* + * Copyright 2013, Ingo Weinhold, ingo_weinhold@gmx.de. + * Distributed under the terms of the MIT License. + */ +#ifndef _KERNEL_DEBUG_HEX_DUMP_H +#define _KERNEL_DEBUG_HEX_DUMP_H + + +#include + + +namespace BKernel { + + +enum { + HEX_DUMP_FLAG_OMIT_ADDRESS = 0x01 +}; + + +class HexDumpDataProvider { +public: + virtual ~HexDumpDataProvider(); + + virtual bool HasMoreData() const = 0; + virtual uint8 NextByte() = 0; + virtual bool GetAddressString(char* buffer, + size_t bufferSize) const; +}; + + +class HexDumpBufferDataProvider : public HexDumpDataProvider { +public: + HexDumpBufferDataProvider(const void* data, + size_t dataSize); + + virtual bool HasMoreData() const; + virtual uint8 NextByte(); + virtual bool GetAddressString(char* buffer, + size_t bufferSize) const; + +private: + const uint8* fData; + size_t fDataSize; +}; + + +void print_hex_dump(HexDumpDataProvider& data, size_t maxBytes, + uint32 flags = 0); +void print_hex_dump(const void* data, size_t maxBytes, uint32 flags = 0); + + +} // namespace BKernel + + +#endif /* _KERNEL_DEBUG_HEX_DUMP_H */ diff --git a/src/system/kernel/debug/Jamfile b/src/system/kernel/debug/Jamfile index 076e240496..9973af2c66 100644 --- a/src/system/kernel/debug/Jamfile +++ b/src/system/kernel/debug/Jamfile @@ -15,6 +15,7 @@ KernelMergeObject kernel_debug.o : debug_builtin_commands.cpp debug_commands.cpp debug_heap.cpp + debug_hex_dump.cpp debug_paranoia.cpp debug_parser.cpp debug_variables.cpp diff --git a/src/system/kernel/debug/debug_hex_dump.cpp b/src/system/kernel/debug/debug_hex_dump.cpp new file mode 100644 index 0000000000..13e9e46e97 --- /dev/null +++ b/src/system/kernel/debug/debug_hex_dump.cpp @@ -0,0 +1,133 @@ +/* + * Copyright 2013, Ingo Weinhold, ingo_weinhold@gmx.de. + * Distributed under the terms of the MIT License. + */ + + +#include + +#include +#include + + +namespace BKernel { + + +// #pragma mark - HexDumpDataProvider + + +HexDumpDataProvider::~HexDumpDataProvider() +{ +} + + +bool +HexDumpDataProvider::GetAddressString(char* buffer, size_t bufferSize) const +{ + return false; +} + + +// #pragma mark - HexDumpBufferDataProvider + + +HexDumpBufferDataProvider::HexDumpBufferDataProvider(const void* data, + size_t dataSize) + : + fData((const uint8*)data), + fDataSize(dataSize) +{ +} + + +bool +HexDumpBufferDataProvider::HasMoreData() const +{ + return fDataSize > 0; +} + + +uint8 +HexDumpBufferDataProvider::NextByte() +{ + if (fDataSize == 0) + return '\0'; + + fDataSize--; + return *fData++; +} + + +bool +HexDumpBufferDataProvider::GetAddressString(char* buffer, + size_t bufferSize) const +{ + snprintf(buffer, bufferSize, "%p", fData); + return true; +} + + +// #pragma mark - + + +void +print_hex_dump(HexDumpDataProvider& data, size_t maxBytes, uint32 flags) +{ + static const size_t kBytesPerBlock = 4; + static const size_t kBytesPerLine = 16; + + size_t i = 0; + for (; i < maxBytes && data.HasMoreData();) { + if (i > 0) + kputs("\n"); + + // print address + uint8 buffer[kBytesPerLine]; + if ((flags & HEX_DUMP_FLAG_OMIT_ADDRESS) == 0 + && data.GetAddressString((char*)buffer, sizeof(buffer))) { + kputs((char*)buffer); + kputs(": "); + } + + // get the line data + size_t bytesInLine = 0; + for (; i < maxBytes && bytesInLine < kBytesPerLine + && data.HasMoreData(); + i++) { + buffer[bytesInLine++] = data.NextByte(); + } + + // print hex representation + for (size_t k = 0; k < bytesInLine; k++) { + if (k > 0 && k % kBytesPerBlock == 0) + kputs(" "); + kprintf("%02x", buffer[k]); + } + + // pad to align the text representation, if line is incomplete + if (bytesInLine < kBytesPerLine) { + int missingBytes = int(kBytesPerLine - bytesInLine); + kprintf("%*s", + 2 * missingBytes + int(missingBytes / kBytesPerBlock), ""); + } + + // print character representation + kputs(" "); + for (size_t k = 0; k < bytesInLine; k++) + kprintf("%c", isprint(buffer[k]) ? buffer[k] : '.'); + } + + if (i > 0) + kputs("\n"); +} + + +void +print_hex_dump(const void* data, size_t maxBytes, uint32 flags) +{ + HexDumpBufferDataProvider dataProvider(data, maxBytes); + print_hex_dump(dataProvider, maxBytes, flags); +} + + +} // namespace BKernel