xref: /llvm-project/lldb/unittests/Core/DumpDataExtractorTest.cpp (revision d950157f7b290e35ce25647e255df9dccbcead2b)
18fdfc1d6SDavid Spickett //===-- DataDumpExtractorTest.cpp -----------------------------------------===//
28fdfc1d6SDavid Spickett //
38fdfc1d6SDavid Spickett // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
48fdfc1d6SDavid Spickett // See https://llvm.org/LICENSE.txt for license information.
58fdfc1d6SDavid Spickett // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
68fdfc1d6SDavid Spickett //
78fdfc1d6SDavid Spickett //===----------------------------------------------------------------------===//
88fdfc1d6SDavid Spickett 
98fdfc1d6SDavid Spickett #include "lldb/Core/DumpDataExtractor.h"
10014c41d6SWalter Erquinigo #include "lldb/Host/FileSystem.h"
11014c41d6SWalter Erquinigo #include "lldb/Host/HostInfo.h"
128fdfc1d6SDavid Spickett #include "lldb/Utility/DataBufferHeap.h"
138fdfc1d6SDavid Spickett #include "lldb/Utility/DataExtractor.h"
148fdfc1d6SDavid Spickett #include "lldb/Utility/Endian.h"
158fdfc1d6SDavid Spickett #include "lldb/Utility/StreamString.h"
168fdfc1d6SDavid Spickett #include "gtest/gtest.h"
178fdfc1d6SDavid Spickett #include <complex>
18ae58cf5fSRaphael Isemann #include <limits>
198fdfc1d6SDavid Spickett 
208fdfc1d6SDavid Spickett using namespace lldb;
218fdfc1d6SDavid Spickett using namespace lldb_private;
228fdfc1d6SDavid Spickett 
23014c41d6SWalter Erquinigo // This is needed for the tests because they rely on the Target global
24014c41d6SWalter Erquinigo // properties.
25014c41d6SWalter Erquinigo class DumpDataExtractorTest : public ::testing::Test {
26014c41d6SWalter Erquinigo public:
SetUp()27014c41d6SWalter Erquinigo   void SetUp() override {
28014c41d6SWalter Erquinigo     FileSystem::Initialize();
29014c41d6SWalter Erquinigo     HostInfo::Initialize();
30014c41d6SWalter Erquinigo   }
TearDown()31014c41d6SWalter Erquinigo   void TearDown() override {
32014c41d6SWalter Erquinigo     HostInfo::Terminate();
33014c41d6SWalter Erquinigo     FileSystem::Terminate();
34014c41d6SWalter Erquinigo   }
35014c41d6SWalter Erquinigo };
36014c41d6SWalter Erquinigo 
TestDumpWithAddress(uint64_t base_addr,size_t item_count,llvm::StringRef expected)3744d0ad53SDavid Spickett static void TestDumpWithAddress(uint64_t base_addr, size_t item_count,
388fdfc1d6SDavid Spickett                                 llvm::StringRef expected) {
39a86cbd47SDavid Spickett   std::vector<uint8_t> data{0x11, 0x22};
40a86cbd47SDavid Spickett   StreamString result;
41a86cbd47SDavid Spickett   DataBufferHeap dumpbuffer(&data[0], data.size());
42a86cbd47SDavid Spickett   DataExtractor extractor(dumpbuffer.GetBytes(), dumpbuffer.GetByteSize(),
43a86cbd47SDavid Spickett                           endian::InlHostByteOrder(), /*addr_size=*/4);
44a86cbd47SDavid Spickett 
45a86cbd47SDavid Spickett   DumpDataExtractor(extractor, &result, 0, lldb::Format::eFormatHex,
46a86cbd47SDavid Spickett                     /*item_byte_size=*/1, item_count,
47a86cbd47SDavid Spickett                     /*num_per_line=*/1, base_addr, 0, 0);
48a86cbd47SDavid Spickett   ASSERT_EQ(expected, result.GetString());
49a86cbd47SDavid Spickett }
50a86cbd47SDavid Spickett 
TEST_F(DumpDataExtractorTest,BaseAddress)51266630cfSWalter Erquinigo TEST_F(DumpDataExtractorTest, BaseAddress) {
5244d0ad53SDavid Spickett   TestDumpWithAddress(0x12341234, 1, "0x12341234: 0x11");
5344d0ad53SDavid Spickett   TestDumpWithAddress(LLDB_INVALID_ADDRESS, 1, "0x11");
5444d0ad53SDavid Spickett   TestDumpWithAddress(0x12341234, 2, "0x12341234: 0x11\n0x12341235: 0x22");
5544d0ad53SDavid Spickett   TestDumpWithAddress(LLDB_INVALID_ADDRESS, 2, "0x11\n0x22");
56a86cbd47SDavid Spickett }
57a86cbd47SDavid Spickett 
TestDumpWithOffset(offset_t start_offset,llvm::StringRef expected)5844d0ad53SDavid Spickett static void TestDumpWithOffset(offset_t start_offset,
59a86cbd47SDavid Spickett                                llvm::StringRef expected) {
60a86cbd47SDavid Spickett   std::vector<uint8_t> data{0x11, 0x22, 0x33};
61a86cbd47SDavid Spickett   StreamString result;
62a86cbd47SDavid Spickett   DataBufferHeap dumpbuffer(&data[0], data.size());
63a86cbd47SDavid Spickett   DataExtractor extractor(dumpbuffer.GetBytes(), dumpbuffer.GetByteSize(),
64a86cbd47SDavid Spickett                           endian::InlHostByteOrder(), /*addr_size=*/4);
65a86cbd47SDavid Spickett 
66a86cbd47SDavid Spickett   DumpDataExtractor(extractor, &result, start_offset, lldb::Format::eFormatHex,
67a86cbd47SDavid Spickett                     /*item_byte_size=*/1, /*item_count=*/data.size(),
68a86cbd47SDavid Spickett                     /*num_per_line=*/data.size(), /*base_addr=*/0, 0, 0);
69a86cbd47SDavid Spickett   ASSERT_EQ(expected, result.GetString());
70a86cbd47SDavid Spickett }
71a86cbd47SDavid Spickett 
TEST_F(DumpDataExtractorTest,StartOffset)72266630cfSWalter Erquinigo TEST_F(DumpDataExtractorTest, StartOffset) {
7344d0ad53SDavid Spickett   TestDumpWithOffset(0, "0x00000000: 0x11 0x22 0x33");
74a86cbd47SDavid Spickett   // The offset applies to the DataExtractor, not the address used when
75a86cbd47SDavid Spickett   // formatting.
7644d0ad53SDavid Spickett   TestDumpWithOffset(1, "0x00000000: 0x22 0x33");
77a86cbd47SDavid Spickett   // If the offset is outside the DataExtractor's range we do nothing.
7844d0ad53SDavid Spickett   TestDumpWithOffset(3, "");
79a86cbd47SDavid Spickett }
80a86cbd47SDavid Spickett 
TEST_F(DumpDataExtractorTest,NullStream)81266630cfSWalter Erquinigo TEST_F(DumpDataExtractorTest, NullStream) {
82a86cbd47SDavid Spickett   // We don't do any work if there is no output stream.
83a86cbd47SDavid Spickett   uint8_t c = 0x11;
84a86cbd47SDavid Spickett   StreamString result;
85a86cbd47SDavid Spickett   DataBufferHeap dumpbuffer(&c, 0);
86a86cbd47SDavid Spickett   DataExtractor extractor(dumpbuffer.GetBytes(), dumpbuffer.GetByteSize(),
87a86cbd47SDavid Spickett                           endian::InlHostByteOrder(), /*addr_size=*/4);
88a86cbd47SDavid Spickett 
89a86cbd47SDavid Spickett   DumpDataExtractor(extractor, nullptr, 0, lldb::Format::eFormatHex,
90a86cbd47SDavid Spickett                     /*item_byte_size=*/1, /*item_count=*/1,
91a86cbd47SDavid Spickett                     /*num_per_line=*/1, /*base_addr=*/0, 0, 0);
92a86cbd47SDavid Spickett   ASSERT_EQ("", result.GetString());
93a86cbd47SDavid Spickett }
94a86cbd47SDavid Spickett 
TestDumpImpl(const void * data,size_t data_size,size_t item_byte_size,size_t item_count,size_t num_per_line,uint64_t base_addr,lldb::Format format,llvm::StringRef expected)95a86cbd47SDavid Spickett static void TestDumpImpl(const void *data, size_t data_size,
96a86cbd47SDavid Spickett                          size_t item_byte_size, size_t item_count,
97a86cbd47SDavid Spickett                          size_t num_per_line, uint64_t base_addr,
98a86cbd47SDavid Spickett                          lldb::Format format, llvm::StringRef expected) {
998fdfc1d6SDavid Spickett   StreamString result;
1008fdfc1d6SDavid Spickett   DataBufferHeap dumpbuffer(data, data_size);
1018fdfc1d6SDavid Spickett   DataExtractor extractor(dumpbuffer.GetBytes(), dumpbuffer.GetByteSize(),
1028fdfc1d6SDavid Spickett                           endian::InlHostByteOrder(),
1038fdfc1d6SDavid Spickett                           /*addr_size=*/4);
104a86cbd47SDavid Spickett   DumpDataExtractor(extractor, &result, 0, format, item_byte_size, item_count,
105a86cbd47SDavid Spickett                     num_per_line, base_addr, 0, 0);
1068fdfc1d6SDavid Spickett   ASSERT_EQ(expected, result.GetString());
1078fdfc1d6SDavid Spickett }
1088fdfc1d6SDavid Spickett 
1098fdfc1d6SDavid Spickett template <typename T>
TestDump(T data,lldb::Format format,llvm::StringRef expected)110a86cbd47SDavid Spickett static void TestDump(T data, lldb::Format format, llvm::StringRef expected) {
111a86cbd47SDavid Spickett   TestDumpImpl(&data, sizeof(T), sizeof(T), 1, 1, LLDB_INVALID_ADDRESS, format,
1128fdfc1d6SDavid Spickett                expected);
1138fdfc1d6SDavid Spickett }
1148fdfc1d6SDavid Spickett 
TestDump(llvm::StringRef str,lldb::Format format,llvm::StringRef expected)115a86cbd47SDavid Spickett static void TestDump(llvm::StringRef str, lldb::Format format,
116a86cbd47SDavid Spickett                      llvm::StringRef expected) {
117a86cbd47SDavid Spickett   TestDumpImpl(str.bytes_begin(),
118a86cbd47SDavid Spickett                // +1 to include the NULL char as the last byte
119a86cbd47SDavid Spickett                str.size() + 1, str.size() + 1, 1, 1, LLDB_INVALID_ADDRESS,
120a86cbd47SDavid Spickett                format, expected);
121a86cbd47SDavid Spickett }
122a86cbd47SDavid Spickett 
123a86cbd47SDavid Spickett template <typename T>
TestDump(const std::vector<T> data,lldb::Format format,llvm::StringRef expected)124a86cbd47SDavid Spickett static void TestDump(const std::vector<T> data, lldb::Format format,
125a86cbd47SDavid Spickett                      llvm::StringRef expected) {
126a86cbd47SDavid Spickett   size_t sz_bytes = data.size() * sizeof(T);
127a86cbd47SDavid Spickett   TestDumpImpl(&data[0], sz_bytes, sz_bytes, data.size(), 1,
128a86cbd47SDavid Spickett                LLDB_INVALID_ADDRESS, format, expected);
129a86cbd47SDavid Spickett }
130a86cbd47SDavid Spickett 
TEST_F(DumpDataExtractorTest,Formats)131266630cfSWalter Erquinigo TEST_F(DumpDataExtractorTest, Formats) {
132a86cbd47SDavid Spickett   TestDump<uint8_t>(1, lldb::eFormatDefault, "0x01");
133a86cbd47SDavid Spickett   TestDump<uint8_t>(1, lldb::eFormatBoolean, "true");
134a86cbd47SDavid Spickett   TestDump<uint8_t>(0xAA, lldb::eFormatBinary, "0b10101010");
135a86cbd47SDavid Spickett   TestDump<uint8_t>(1, lldb::eFormatBytes, "01");
136a86cbd47SDavid Spickett   TestDump<uint8_t>(1, lldb::eFormatBytesWithASCII, "01  .");
137a86cbd47SDavid Spickett   TestDump('?', lldb::eFormatChar, "'?'");
138a86cbd47SDavid Spickett   TestDump('\x1A', lldb::eFormatCharPrintable, ".");
139a86cbd47SDavid Spickett   TestDump('#', lldb::eFormatCharPrintable, "#");
140*d950157fSAlexandre Ganea   TestDump(std::complex<float>(1.2f, 3.4f), lldb::eFormatComplex, "1.2 + 3.4i");
141a86cbd47SDavid Spickett   TestDump(std::complex<double>(4.5, 6.7), lldb::eFormatComplex, "4.5 + 6.7i");
1428fdfc1d6SDavid Spickett 
1438fdfc1d6SDavid Spickett   // long double is not tested here because for some platforms we treat it as 10
1448fdfc1d6SDavid Spickett   // bytes when the compiler allocates 16 bytes of space for it. (see
1458fdfc1d6SDavid Spickett   // DataExtractor::GetLongDouble) Meaning that when we extract the second one,
1468fdfc1d6SDavid Spickett   // it gets the wrong value (it's 6 bytes off). You could manually construct a
1478fdfc1d6SDavid Spickett   // set of bytes to match the 10 byte format but then if the test runs on a
1488fdfc1d6SDavid Spickett   // machine where we don't use 10 it'll break.
1498fdfc1d6SDavid Spickett 
15085f40fc6SJonas Devlieghere   // Test printable characters.
151a86cbd47SDavid Spickett   TestDump(llvm::StringRef("aardvark"), lldb::Format::eFormatCString,
152a86cbd47SDavid Spickett            "\"aardvark\"");
15385f40fc6SJonas Devlieghere   // Test unprintable characters.
15485f40fc6SJonas Devlieghere   TestDump(llvm::StringRef("\xcf\xfa\xed\xfe\f"), lldb::Format::eFormatCString,
15585f40fc6SJonas Devlieghere            "\"\\xcf\\xfa\\xed\\xfe\\f\"");
15685f40fc6SJonas Devlieghere   // Test a mix of printable and unprintable characters.
15785f40fc6SJonas Devlieghere   TestDump(llvm::StringRef("\xcf\xfa\ffoo"), lldb::Format::eFormatCString,
15885f40fc6SJonas Devlieghere            "\"\\xcf\\xfa\\ffoo\"");
15985f40fc6SJonas Devlieghere 
160a86cbd47SDavid Spickett   TestDump<uint16_t>(99, lldb::Format::eFormatDecimal, "99");
1618fdfc1d6SDavid Spickett   // Just prints as a signed integer.
162a86cbd47SDavid Spickett   TestDump(-1, lldb::Format::eFormatEnum, "-1");
163a86cbd47SDavid Spickett   TestDump(0xcafef00d, lldb::Format::eFormatHex, "0xcafef00d");
164a86cbd47SDavid Spickett   TestDump(0xcafef00d, lldb::Format::eFormatHexUppercase, "0xCAFEF00D");
1651400a3cbSPavel Labath   TestDump(0.456, lldb::Format::eFormatFloat, "0.45600000000000002");
166a86cbd47SDavid Spickett   TestDump(9, lldb::Format::eFormatOctal, "011");
1678fdfc1d6SDavid Spickett   // Chars packed into an integer.
168a86cbd47SDavid Spickett   TestDump<uint32_t>(0x4C4C4442, lldb::Format::eFormatOSType, "'LLDB'");
1698fdfc1d6SDavid Spickett   // Unicode8 doesn't have a specific formatter.
170a86cbd47SDavid Spickett   TestDump<uint8_t>(0x34, lldb::Format::eFormatUnicode8, "0x34");
171a86cbd47SDavid Spickett   TestDump<uint16_t>(0x1122, lldb::Format::eFormatUnicode16, "U+1122");
172a86cbd47SDavid Spickett   TestDump<uint32_t>(0x12345678, lldb::Format::eFormatUnicode32,
173a86cbd47SDavid Spickett                      "U+0x12345678");
174a86cbd47SDavid Spickett   TestDump<unsigned int>(654321, lldb::Format::eFormatUnsigned, "654321");
1758fdfc1d6SDavid Spickett   // This pointer is printed based on the size of uint64_t, so the test is the
1768fdfc1d6SDavid Spickett   // same for 32/64 bit host.
177a86cbd47SDavid Spickett   TestDump<uint64_t>(0x4444555566667777, lldb::Format::eFormatPointer,
178a86cbd47SDavid Spickett                      "0x4444555566667777");
1798fdfc1d6SDavid Spickett 
180a86cbd47SDavid Spickett   TestDump(std::vector<char>{'A', '\x01', 'C'},
181a86cbd47SDavid Spickett            lldb::Format::eFormatVectorOfChar, "{A\\x01C}");
182a86cbd47SDavid Spickett   TestDump(std::vector<int8_t>{0, -1, std::numeric_limits<int8_t>::max()},
183a86cbd47SDavid Spickett            lldb::Format::eFormatVectorOfSInt8, "{0 -1 127}");
184a86cbd47SDavid Spickett   TestDump(std::vector<uint8_t>{12, 0xFF, 34},
185a86cbd47SDavid Spickett            lldb::Format::eFormatVectorOfUInt8, "{0x0c 0xff 0x22}");
186a86cbd47SDavid Spickett   TestDump(std::vector<int16_t>{-1, 1234, std::numeric_limits<int16_t>::max()},
187a86cbd47SDavid Spickett            lldb::Format::eFormatVectorOfSInt16, "{-1 1234 32767}");
188a86cbd47SDavid Spickett   TestDump(std::vector<uint16_t>{0xffff, 0xabcd, 0x1234},
189a86cbd47SDavid Spickett            lldb::Format::eFormatVectorOfUInt16, "{0xffff 0xabcd 0x1234}");
190a86cbd47SDavid Spickett   TestDump(std::vector<int32_t>{0, -1, std::numeric_limits<int32_t>::max()},
191a86cbd47SDavid Spickett            lldb::Format::eFormatVectorOfSInt32, "{0 -1 2147483647}");
192a86cbd47SDavid Spickett   TestDump(std::vector<uint32_t>{0, 0xffffffff, 0x1234abcd},
1938fdfc1d6SDavid Spickett            lldb::Format::eFormatVectorOfUInt32,
194a86cbd47SDavid Spickett            "{0x00000000 0xffffffff 0x1234abcd}");
195a86cbd47SDavid Spickett   TestDump(std::vector<int64_t>{0, -1, std::numeric_limits<int64_t>::max()},
196a86cbd47SDavid Spickett            lldb::Format::eFormatVectorOfSInt64, "{0 -1 9223372036854775807}");
197a86cbd47SDavid Spickett   TestDump(std::vector<uint64_t>{0, 0xaaaabbbbccccdddd},
1988fdfc1d6SDavid Spickett            lldb::Format::eFormatVectorOfUInt64,
199a86cbd47SDavid Spickett            "{0x0000000000000000 0xaaaabbbbccccdddd}");
2008fdfc1d6SDavid Spickett 
2018fdfc1d6SDavid Spickett   // See half2float for format details.
20248780527SRaphael Isemann   // Test zeroes.
20348780527SRaphael Isemann   TestDump(std::vector<uint16_t>{0x0000, 0x8000},
20448780527SRaphael Isemann            lldb::Format::eFormatVectorOfFloat16, "{0 -0}");
20548780527SRaphael Isemann   // Some subnormal numbers.
20648780527SRaphael Isemann   TestDump(std::vector<uint16_t>{0x0001, 0x8001},
2071400a3cbSPavel Labath            lldb::Format::eFormatVectorOfFloat16, "{5.9605E-8 -5.9605E-8}");
20848780527SRaphael Isemann   // A full mantisse and empty expontent.
20948780527SRaphael Isemann   TestDump(std::vector<uint16_t>{0x83ff, 0x03ff},
2101400a3cbSPavel Labath            lldb::Format::eFormatVectorOfFloat16, "{-6.0976E-5 6.0976E-5}");
21148780527SRaphael Isemann   // Some normal numbers.
21248780527SRaphael Isemann   TestDump(std::vector<uint16_t>{0b0100001001001000},
2131400a3cbSPavel Labath            lldb::Format::eFormatVectorOfFloat16, "{3.1406}");
21448780527SRaphael Isemann   // Largest and smallest normal number.
21548780527SRaphael Isemann   TestDump(std::vector<uint16_t>{0x0400, 0x7bff},
2161400a3cbSPavel Labath            lldb::Format::eFormatVectorOfFloat16, "{6.1035E-5 65504}");
217a86cbd47SDavid Spickett   TestDump(std::vector<uint16_t>{0xabcd, 0x1234},
2181400a3cbSPavel Labath            lldb::Format::eFormatVectorOfFloat16, "{-0.060944 7.5722E-4}");
219ae58cf5fSRaphael Isemann 
220ae58cf5fSRaphael Isemann   // quiet/signaling NaNs.
221ae58cf5fSRaphael Isemann   TestDump(std::vector<uint16_t>{0xffff, 0xffc0, 0x7fff, 0x7fc0},
2221400a3cbSPavel Labath            lldb::Format::eFormatVectorOfFloat16, "{NaN NaN NaN NaN}");
223ae58cf5fSRaphael Isemann   // +/-Inf.
224ae58cf5fSRaphael Isemann   TestDump(std::vector<uint16_t>{0xfc00, 0x7c00},
2251400a3cbSPavel Labath            lldb::Format::eFormatVectorOfFloat16, "{-Inf +Inf}");
226ae58cf5fSRaphael Isemann 
227a86cbd47SDavid Spickett   TestDump(std::vector<float>{std::numeric_limits<float>::min(),
2288fdfc1d6SDavid Spickett                               std::numeric_limits<float>::max()},
2291400a3cbSPavel Labath            lldb::Format::eFormatVectorOfFloat32,
2301400a3cbSPavel Labath            "{1.17549435E-38 3.40282347E+38}");
231ae58cf5fSRaphael Isemann   TestDump(std::vector<float>{std::numeric_limits<float>::quiet_NaN(),
232ae58cf5fSRaphael Isemann                               std::numeric_limits<float>::signaling_NaN(),
233ae58cf5fSRaphael Isemann                               -std::numeric_limits<float>::quiet_NaN(),
234ae58cf5fSRaphael Isemann                               -std::numeric_limits<float>::signaling_NaN()},
2351400a3cbSPavel Labath            lldb::Format::eFormatVectorOfFloat32, "{NaN NaN NaN NaN}");
236a86cbd47SDavid Spickett   TestDump(std::vector<double>{std::numeric_limits<double>::min(),
2378fdfc1d6SDavid Spickett                                std::numeric_limits<double>::max()},
2388fdfc1d6SDavid Spickett            lldb::Format::eFormatVectorOfFloat64,
2391400a3cbSPavel Labath            "{2.2250738585072014E-308 1.7976931348623157E+308}");
240ae58cf5fSRaphael Isemann   TestDump(
241ae58cf5fSRaphael Isemann       std::vector<double>{
242ae58cf5fSRaphael Isemann           std::numeric_limits<double>::quiet_NaN(),
243ae58cf5fSRaphael Isemann           std::numeric_limits<double>::signaling_NaN(),
244ae58cf5fSRaphael Isemann           -std::numeric_limits<double>::quiet_NaN(),
245ae58cf5fSRaphael Isemann           -std::numeric_limits<double>::signaling_NaN(),
246ae58cf5fSRaphael Isemann       },
2471400a3cbSPavel Labath       lldb::Format::eFormatVectorOfFloat64, "{NaN NaN NaN NaN}");
2488fdfc1d6SDavid Spickett 
2498fdfc1d6SDavid Spickett   // Not sure we can rely on having uint128_t everywhere so emulate with
2508fdfc1d6SDavid Spickett   // uint64_t.
251a86cbd47SDavid Spickett   TestDump(
2528fdfc1d6SDavid Spickett       std::vector<uint64_t>{0x1, 0x1111222233334444, 0xaaaabbbbccccdddd, 0x0},
2538fdfc1d6SDavid Spickett       lldb::Format::eFormatVectorOfUInt128,
254a86cbd47SDavid Spickett       "{0x11112222333344440000000000000001 "
2558fdfc1d6SDavid Spickett       "0x0000000000000000aaaabbbbccccdddd}");
2568fdfc1d6SDavid Spickett 
257a86cbd47SDavid Spickett   TestDump(std::vector<int>{2, 4}, lldb::Format::eFormatComplexInteger,
258a86cbd47SDavid Spickett            "2 + 4i");
2598fdfc1d6SDavid Spickett 
2608fdfc1d6SDavid Spickett   // Without an execution context this just prints the pointer on its own.
261a86cbd47SDavid Spickett   TestDump<uint32_t>(0x11223344, lldb::Format::eFormatAddressInfo,
262a86cbd47SDavid Spickett                      "0x11223344");
2638fdfc1d6SDavid Spickett 
2648fdfc1d6SDavid Spickett   // Input not written in hex form because that requires C++17.
265a86cbd47SDavid Spickett   TestDump<float>(10, lldb::Format::eFormatHexFloat, "0x1.4p3");
266a86cbd47SDavid Spickett   TestDump<double>(10, lldb::Format::eFormatHexFloat, "0x1.4p3");
2678da5d111SDavid Spickett   // long double not supported, see ItemByteSizeErrors.
2688fdfc1d6SDavid Spickett 
2698fdfc1d6SDavid Spickett   // Can't disassemble without an execution context.
270a86cbd47SDavid Spickett   TestDump<uint32_t>(0xcafef00d, lldb::Format::eFormatInstruction,
2718fdfc1d6SDavid Spickett                      "invalid target");
2728fdfc1d6SDavid Spickett 
2738fdfc1d6SDavid Spickett   // Has no special handling, intended for use elsewhere.
274a86cbd47SDavid Spickett   TestDump<int>(99, lldb::Format::eFormatVoid, "0x00000063");
2758fdfc1d6SDavid Spickett }
2768fdfc1d6SDavid Spickett 
TEST_F(DumpDataExtractorTest,FormatCharArray)277266630cfSWalter Erquinigo TEST_F(DumpDataExtractorTest, FormatCharArray) {
2788fdfc1d6SDavid Spickett   // Unlike the other formats, charArray isn't 1 array of N chars.
2798fdfc1d6SDavid Spickett   // It must be passed as N chars of 1 byte each.
2808fdfc1d6SDavid Spickett   // (eFormatVectorOfChar does this swap for you)
2818fdfc1d6SDavid Spickett   std::vector<char> data{'A', '\x01', '#'};
2828fdfc1d6SDavid Spickett   StreamString result;
2838fdfc1d6SDavid Spickett   DataBufferHeap dumpbuffer(&data[0], data.size());
2848fdfc1d6SDavid Spickett   DataExtractor extractor(dumpbuffer.GetBytes(), dumpbuffer.GetByteSize(),
2858fdfc1d6SDavid Spickett                           endian::InlHostByteOrder(), /*addr_size=*/4);
2868fdfc1d6SDavid Spickett 
2878fdfc1d6SDavid Spickett   DumpDataExtractor(extractor, &result, 0, lldb::Format::eFormatCharArray,
2888fdfc1d6SDavid Spickett                     /*item_byte_size=*/1,
2898fdfc1d6SDavid Spickett                     /*item_count=*/data.size(),
2908fdfc1d6SDavid Spickett                     /*num_per_line=*/data.size(), 0, 0, 0);
2918fdfc1d6SDavid Spickett   ASSERT_EQ("0x00000000: A\\x01#", result.GetString());
2928fdfc1d6SDavid Spickett 
2938fdfc1d6SDavid Spickett   result.Clear();
2948fdfc1d6SDavid Spickett   DumpDataExtractor(extractor, &result, 0, lldb::Format::eFormatCharArray, 1,
2958fdfc1d6SDavid Spickett                     data.size(), 1, 0, 0, 0);
2968fdfc1d6SDavid Spickett   // ASSERT macro thinks the split strings are multiple arguments so make a var.
2978fdfc1d6SDavid Spickett   const char *expected = "0x00000000: A\n"
2988fdfc1d6SDavid Spickett                          "0x00000001: \\x01\n"
2998fdfc1d6SDavid Spickett                          "0x00000002: #";
3008fdfc1d6SDavid Spickett   ASSERT_EQ(expected, result.GetString());
3018fdfc1d6SDavid Spickett }
302a86cbd47SDavid Spickett 
303a86cbd47SDavid Spickett template <typename T>
TestDumpMultiLine(std::vector<T> data,lldb::Format format,size_t num_per_line,llvm::StringRef expected)30444d0ad53SDavid Spickett void TestDumpMultiLine(std::vector<T> data, lldb::Format format,
305a86cbd47SDavid Spickett                        size_t num_per_line, llvm::StringRef expected) {
306a86cbd47SDavid Spickett   size_t sz_bytes = data.size() * sizeof(T);
307a86cbd47SDavid Spickett   TestDumpImpl(&data[0], sz_bytes, data.size(), sz_bytes, num_per_line,
308a86cbd47SDavid Spickett                0x80000000, format, expected);
309a86cbd47SDavid Spickett }
310a86cbd47SDavid Spickett 
311a86cbd47SDavid Spickett template <typename T>
TestDumpMultiLine(const T * data,size_t num_items,lldb::Format format,size_t num_per_line,llvm::StringRef expected)31244d0ad53SDavid Spickett void TestDumpMultiLine(const T *data, size_t num_items, lldb::Format format,
313a86cbd47SDavid Spickett                        size_t num_per_line, llvm::StringRef expected) {
314a86cbd47SDavid Spickett   TestDumpImpl(data, sizeof(T) * num_items, sizeof(T), num_items, num_per_line,
315a86cbd47SDavid Spickett                0x80000000, format, expected);
316a86cbd47SDavid Spickett }
317a86cbd47SDavid Spickett 
TEST_F(DumpDataExtractorTest,MultiLine)318266630cfSWalter Erquinigo TEST_F(DumpDataExtractorTest, MultiLine) {
319a86cbd47SDavid Spickett   // A vector counts as 1 item regardless of size.
32044d0ad53SDavid Spickett   TestDumpMultiLine(std::vector<uint8_t>{0x11},
321a86cbd47SDavid Spickett                     lldb::Format::eFormatVectorOfUInt8, 1,
322a86cbd47SDavid Spickett                     "0x80000000: {0x11}");
32344d0ad53SDavid Spickett   TestDumpMultiLine(std::vector<uint8_t>{0x11, 0x22},
324a86cbd47SDavid Spickett                     lldb::Format::eFormatVectorOfUInt8, 1,
325a86cbd47SDavid Spickett                     "0x80000000: {0x11 0x22}");
326a86cbd47SDavid Spickett 
327a86cbd47SDavid Spickett   // If you have multiple vectors then that's multiple items.
328a86cbd47SDavid Spickett   // Here we say that these 2 bytes are actually 2 1 byte vectors.
329a86cbd47SDavid Spickett   const std::vector<uint8_t> vector_data{0x11, 0x22};
33044d0ad53SDavid Spickett   TestDumpMultiLine(vector_data.data(), 2, lldb::Format::eFormatVectorOfUInt8,
331a86cbd47SDavid Spickett                     1, "0x80000000: {0x11}\n0x80000001: {0x22}");
332a86cbd47SDavid Spickett 
333a86cbd47SDavid Spickett   // Single value formats can span multiple lines.
334a86cbd47SDavid Spickett   const std::vector<uint8_t> bytes{0x11, 0x22, 0x33};
335a86cbd47SDavid Spickett   const char *expected_bytes_3_line = "0x80000000: 0x11\n"
336a86cbd47SDavid Spickett                                       "0x80000001: 0x22\n"
337a86cbd47SDavid Spickett                                       "0x80000002: 0x33";
33844d0ad53SDavid Spickett   TestDumpMultiLine(bytes.data(), bytes.size(), lldb::Format::eFormatHex, 1,
339a86cbd47SDavid Spickett                     expected_bytes_3_line);
340a86cbd47SDavid Spickett 
341a86cbd47SDavid Spickett   // Lines may not have the full number of items.
34244d0ad53SDavid Spickett   TestDumpMultiLine(bytes.data(), bytes.size(), lldb::Format::eFormatHex, 4,
343a86cbd47SDavid Spickett                     "0x80000000: 0x11 0x22 0x33");
344a86cbd47SDavid Spickett   const char *expected_bytes_2_line = "0x80000000: 0x11 0x22\n"
345a86cbd47SDavid Spickett                                       "0x80000002: 0x33";
34644d0ad53SDavid Spickett   TestDumpMultiLine(bytes.data(), bytes.size(), lldb::Format::eFormatHex, 2,
347a86cbd47SDavid Spickett                     expected_bytes_2_line);
348a86cbd47SDavid Spickett 
349a86cbd47SDavid Spickett   // The line address accounts for item sizes other than 1 byte.
350a86cbd47SDavid Spickett   const std::vector<uint16_t> shorts{0x1111, 0x2222, 0x3333};
351a86cbd47SDavid Spickett   const char *expected_shorts_2_line = "0x80000000: 0x1111 0x2222\n"
352a86cbd47SDavid Spickett                                        "0x80000004: 0x3333";
35344d0ad53SDavid Spickett   TestDumpMultiLine(shorts.data(), shorts.size(), lldb::Format::eFormatHex, 2,
354a86cbd47SDavid Spickett                     expected_shorts_2_line);
355a86cbd47SDavid Spickett 
356a86cbd47SDavid Spickett   // The ascii column is positioned using the maximum line length.
357a86cbd47SDavid Spickett   const std::vector<char> chars{'L', 'L', 'D', 'B'};
358a86cbd47SDavid Spickett   const char *expected_chars_2_lines = "0x80000000: 4c 4c 44  LLD\n"
359a86cbd47SDavid Spickett                                        "0x80000003: 42        B";
36044d0ad53SDavid Spickett   TestDumpMultiLine(chars.data(), chars.size(),
361a86cbd47SDavid Spickett                     lldb::Format::eFormatBytesWithASCII, 3,
362a86cbd47SDavid Spickett                     expected_chars_2_lines);
363a86cbd47SDavid Spickett }
3648da5d111SDavid Spickett 
TestDumpWithItemByteSize(size_t item_byte_size,lldb::Format format,llvm::StringRef expected)3658da5d111SDavid Spickett void TestDumpWithItemByteSize(size_t item_byte_size, lldb::Format format,
3668da5d111SDavid Spickett                               llvm::StringRef expected) {
3678da5d111SDavid Spickett   // We won't be reading this data so anything will do.
3688da5d111SDavid Spickett   uint8_t dummy = 0;
3698da5d111SDavid Spickett   TestDumpImpl(&dummy, 1, item_byte_size, 1, 1, LLDB_INVALID_ADDRESS, format,
3708da5d111SDavid Spickett                expected);
3718da5d111SDavid Spickett }
3728da5d111SDavid Spickett 
TEST_F(DumpDataExtractorTest,ItemByteSizeErrors)373266630cfSWalter Erquinigo TEST_F(DumpDataExtractorTest, ItemByteSizeErrors) {
3748da5d111SDavid Spickett   TestDumpWithItemByteSize(
3758da5d111SDavid Spickett       16, lldb::Format::eFormatBoolean,
3768da5d111SDavid Spickett       "error: unsupported byte size (16) for boolean format");
3778da5d111SDavid Spickett   TestDumpWithItemByteSize(21, lldb::Format::eFormatChar,
3788da5d111SDavid Spickett                            "error: unsupported byte size (21) for char format");
3798da5d111SDavid Spickett   TestDumpWithItemByteSize(
3808da5d111SDavid Spickett       18, lldb::Format::eFormatComplexInteger,
3818da5d111SDavid Spickett       "error: unsupported byte size (18) for complex integer format");
3828da5d111SDavid Spickett 
3838da5d111SDavid Spickett   // The code uses sizeof(long double) for these checks. This changes by host
3848da5d111SDavid Spickett   // but we know it won't be >16.
3858da5d111SDavid Spickett   TestDumpWithItemByteSize(
3868da5d111SDavid Spickett       34, lldb::Format::eFormatComplex,
3878da5d111SDavid Spickett       "error: unsupported byte size (34) for complex float format");
3888da5d111SDavid Spickett   TestDumpWithItemByteSize(
3898da5d111SDavid Spickett       18, lldb::Format::eFormatFloat,
3908da5d111SDavid Spickett       "error: unsupported byte size (18) for float format");
3918da5d111SDavid Spickett 
3928da5d111SDavid Spickett   // We want sizes to exactly match one of float/double.
3938da5d111SDavid Spickett   TestDumpWithItemByteSize(
3948da5d111SDavid Spickett       14, lldb::Format::eFormatComplex,
3958da5d111SDavid Spickett       "error: unsupported byte size (14) for complex float format");
3968da5d111SDavid Spickett   TestDumpWithItemByteSize(3, lldb::Format::eFormatFloat,
3978da5d111SDavid Spickett                            "error: unsupported byte size (3) for float format");
3988da5d111SDavid Spickett 
3998da5d111SDavid Spickett   // We only allow float and double size.
4008da5d111SDavid Spickett   TestDumpWithItemByteSize(
4018da5d111SDavid Spickett       1, lldb::Format::eFormatHexFloat,
4028da5d111SDavid Spickett       "error: unsupported byte size (1) for hex float format");
4038da5d111SDavid Spickett   TestDumpWithItemByteSize(
4048da5d111SDavid Spickett       17, lldb::Format::eFormatHexFloat,
4058da5d111SDavid Spickett       "error: unsupported byte size (17) for hex float format");
4068da5d111SDavid Spickett }
407