diff options
author | Greg Clayton <gclayton@apple.com> | 2016-11-09 00:15:54 +0000 |
---|---|---|
committer | Greg Clayton <gclayton@apple.com> | 2016-11-09 00:15:54 +0000 |
commit | a20694002c0fc014b0e1770be1b1921d1e59a6a3 (patch) | |
tree | fa739d66cd0def5bebd46e7576dc1fee50b3cf36 /lib/Support/raw_ostream.cpp | |
parent | 6382ee0e42d414f6506f97e103892de07f1ad83f (diff) |
Added the ability to dump hex bytes easily into a raw_ostream.
Unit tests were added to verify this functionality keeps working correctly.
Example output for raw hex bytes:
llvm::ArrayRef<uint8_t> Bytes = ...;
llvm::outs() << format_hex_bytes(Bytes);
554889e5 4881ec70 04000048 8d051002
00004c8d 05fd0100 004c8b0d d0020000
Example output for raw hex bytes with offsets:
llvm::outs() << format_hex_bytes(Bytes, 0x100000d10);
0x0000000100000d10: 554889e5 4881ec70 04000048 8d051002
0x0000000100000d20: 00004c8d 05fd0100 004c8b0d d0020000
Example output for raw hex bytes with ASCII with offsets:
llvm::outs() << format_hex_bytes_with_ascii(Bytes, 0x100000d10);
0x0000000100000d10: 554889e5 4881ec70 04000048 8d051002 |UH.?H.?p...H....|
0x0000000100000d20: 00004c8d 05fd0100 004c8b0d d0020000 |..L..?...L..?...|
The default groups bytes into 4 byte groups, but this can be changed to 1 byte:
llvm::outs() << format_hex_bytes(Bytes, 0x100000d10, 16 /*NumPerLine*/, 1 /*ByteGroupSize*/);
0x0000000100000d10: 55 48 89 e5 48 81 ec 70 04 00 00 48 8d 05 10 02
0x0000000100000d20: 00 00 4c 8d 05 fd 01 00 00 4c 8b 0d d0 02 00 00
llvm::outs() << format_hex_bytes(Bytes, 0x100000d10, 16 /*NumPerLine*/, 2 /*ByteGroupSize*/);
0x0000000100000d10: 5548 89e5 4881 ec70 0400 0048 8d05 1002
0x0000000100000d20: 0000 4c8d 05fd 0100 004c 8b0d d002 0000
llvm::outs() << format_hex_bytes(Bytes, 0x100000d10, 8 /*NumPerLine*/, 1 /*ByteGroupSize*/);
0x0000000100000d10: 55 48 89 e5 48 81 ec 70
0x0000000100000d18: 04 00 00 48 8d 05 10 02
0x0000000100000d20: 00 00 4c 8d 05 fd 01 00
0x0000000100000d28: 00 4c 8b 0d d0 02 00 00
https://reviews.llvm.org/D26405
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@286316 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Support/raw_ostream.cpp')
-rw-r--r-- | lib/Support/raw_ostream.cpp | 55 |
1 files changed, 55 insertions, 0 deletions
diff --git a/lib/Support/raw_ostream.cpp b/lib/Support/raw_ostream.cpp index b6835e3ebfe..42f121dbea1 100644 --- a/lib/Support/raw_ostream.cpp +++ b/lib/Support/raw_ostream.cpp @@ -352,6 +352,61 @@ raw_ostream &raw_ostream::operator<<(const FormattedNumber &FN) { return *this; } +raw_ostream &raw_ostream::operator<<(const FormattedHexBytes &FB) { + size_t LineIndex = 0; + const size_t Size = FB.Bytes.size(); + HexPrintStyle OffsetStyle = + FB.Upper ? HexPrintStyle::PrefixUpper : HexPrintStyle::PrefixLower; + HexPrintStyle ByteStyle = + FB.Upper ? HexPrintStyle::Upper : HexPrintStyle::Lower; + while (LineIndex < Size) { + if (FB.FirstByteOffset.hasValue()) { + uint64_t Offset = FB.FirstByteOffset.getValue(); + llvm::write_hex(*this, Offset + LineIndex, OffsetStyle, + sizeof(Offset) * 2 + 2); + *this << ": "; + } + // Print the hex bytes for this line + uint32_t I = 0; + for (I = 0; I < FB.NumPerLine; ++I) { + size_t Index = LineIndex + I; + if (Index >= Size) + break; + if (I && (I % FB.ByteGroupSize) == 0) + *this << " "; + llvm::write_hex(*this, FB.Bytes[Index], ByteStyle, 2); + } + uint32_t BytesDisplayed = I; + if (FB.ASCII) { + // Print any spaces needed for any bytes that we didn't print on this + // line so that the ASCII bytes are correctly aligned. + for (; I < FB.NumPerLine; ++I) { + if (I && (I % FB.ByteGroupSize) == 0) + indent(3); + else + indent(2); + } + *this << " |"; + // Print the ASCII char values for each byte on this line + for (I = 0; I < FB.NumPerLine; ++I) { + size_t Index = LineIndex + I; + if (Index >= Size) + break; + char ch = (char)FB.Bytes[Index]; + if (isprint(ch)) + *this << ch; + else + *this << '.'; + } + *this << '|'; + } + LineIndex += BytesDisplayed; + if (LineIndex < Size) + *this << '\n'; + } + return *this; +} + /// indent - Insert 'NumSpaces' spaces. raw_ostream &raw_ostream::indent(unsigned NumSpaces) { static const char Spaces[] = " " |