[libc][NFC] Move aligned access implementations to separate header
[llvm-project.git] / lldb / unittests / Core / DumpDataExtractorTest.cpp
blobbbe5e9e5ed9e2995562b8bc5f877ad52b296c692
1 //===-- DataDumpExtractorTest.cpp -----------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
9 #include "lldb/Core/DumpDataExtractor.h"
10 #include "lldb/Utility/DataBufferHeap.h"
11 #include "lldb/Utility/DataExtractor.h"
12 #include "lldb/Utility/Endian.h"
13 #include "lldb/Utility/StreamString.h"
14 #include "gtest/gtest.h"
15 #include <complex>
16 #include <limits>
18 using namespace lldb;
19 using namespace lldb_private;
21 static void TestDumpWithAddress(uint64_t base_addr, size_t item_count,
22 llvm::StringRef expected) {
23 std::vector<uint8_t> data{0x11, 0x22};
24 StreamString result;
25 DataBufferHeap dumpbuffer(&data[0], data.size());
26 DataExtractor extractor(dumpbuffer.GetBytes(), dumpbuffer.GetByteSize(),
27 endian::InlHostByteOrder(), /*addr_size=*/4);
29 DumpDataExtractor(extractor, &result, 0, lldb::Format::eFormatHex,
30 /*item_byte_size=*/1, item_count,
31 /*num_per_line=*/1, base_addr, 0, 0);
32 ASSERT_EQ(expected, result.GetString());
35 TEST(DumpDataExtractorTest, BaseAddress) {
36 TestDumpWithAddress(0x12341234, 1, "0x12341234: 0x11");
37 TestDumpWithAddress(LLDB_INVALID_ADDRESS, 1, "0x11");
38 TestDumpWithAddress(0x12341234, 2, "0x12341234: 0x11\n0x12341235: 0x22");
39 TestDumpWithAddress(LLDB_INVALID_ADDRESS, 2, "0x11\n0x22");
42 static void TestDumpWithOffset(offset_t start_offset,
43 llvm::StringRef expected) {
44 std::vector<uint8_t> data{0x11, 0x22, 0x33};
45 StreamString result;
46 DataBufferHeap dumpbuffer(&data[0], data.size());
47 DataExtractor extractor(dumpbuffer.GetBytes(), dumpbuffer.GetByteSize(),
48 endian::InlHostByteOrder(), /*addr_size=*/4);
50 DumpDataExtractor(extractor, &result, start_offset, lldb::Format::eFormatHex,
51 /*item_byte_size=*/1, /*item_count=*/data.size(),
52 /*num_per_line=*/data.size(), /*base_addr=*/0, 0, 0);
53 ASSERT_EQ(expected, result.GetString());
56 TEST(DumpDataExtractorTest, StartOffset) {
57 TestDumpWithOffset(0, "0x00000000: 0x11 0x22 0x33");
58 // The offset applies to the DataExtractor, not the address used when
59 // formatting.
60 TestDumpWithOffset(1, "0x00000000: 0x22 0x33");
61 // If the offset is outside the DataExtractor's range we do nothing.
62 TestDumpWithOffset(3, "");
65 TEST(DumpDataExtractorTest, NullStream) {
66 // We don't do any work if there is no output stream.
67 uint8_t c = 0x11;
68 StreamString result;
69 DataBufferHeap dumpbuffer(&c, 0);
70 DataExtractor extractor(dumpbuffer.GetBytes(), dumpbuffer.GetByteSize(),
71 endian::InlHostByteOrder(), /*addr_size=*/4);
73 DumpDataExtractor(extractor, nullptr, 0, lldb::Format::eFormatHex,
74 /*item_byte_size=*/1, /*item_count=*/1,
75 /*num_per_line=*/1, /*base_addr=*/0, 0, 0);
76 ASSERT_EQ("", result.GetString());
79 static void TestDumpImpl(const void *data, size_t data_size,
80 size_t item_byte_size, size_t item_count,
81 size_t num_per_line, uint64_t base_addr,
82 lldb::Format format, llvm::StringRef expected) {
83 StreamString result;
84 DataBufferHeap dumpbuffer(data, data_size);
85 DataExtractor extractor(dumpbuffer.GetBytes(), dumpbuffer.GetByteSize(),
86 endian::InlHostByteOrder(),
87 /*addr_size=*/4);
88 DumpDataExtractor(extractor, &result, 0, format, item_byte_size, item_count,
89 num_per_line, base_addr, 0, 0);
90 ASSERT_EQ(expected, result.GetString());
93 template <typename T>
94 static void TestDump(T data, lldb::Format format, llvm::StringRef expected) {
95 TestDumpImpl(&data, sizeof(T), sizeof(T), 1, 1, LLDB_INVALID_ADDRESS, format,
96 expected);
99 static void TestDump(llvm::StringRef str, lldb::Format format,
100 llvm::StringRef expected) {
101 TestDumpImpl(str.bytes_begin(),
102 // +1 to include the NULL char as the last byte
103 str.size() + 1, str.size() + 1, 1, 1, LLDB_INVALID_ADDRESS,
104 format, expected);
107 template <typename T>
108 static void TestDump(const std::vector<T> data, lldb::Format format,
109 llvm::StringRef expected) {
110 size_t sz_bytes = data.size() * sizeof(T);
111 TestDumpImpl(&data[0], sz_bytes, sz_bytes, data.size(), 1,
112 LLDB_INVALID_ADDRESS, format, expected);
115 TEST(DumpDataExtractorTest, Formats) {
116 TestDump<uint8_t>(1, lldb::eFormatDefault, "0x01");
117 TestDump<uint8_t>(1, lldb::eFormatBoolean, "true");
118 TestDump<uint8_t>(0xAA, lldb::eFormatBinary, "0b10101010");
119 TestDump<uint8_t>(1, lldb::eFormatBytes, "01");
120 TestDump<uint8_t>(1, lldb::eFormatBytesWithASCII, "01 .");
121 TestDump('?', lldb::eFormatChar, "'?'");
122 TestDump('\x1A', lldb::eFormatCharPrintable, ".");
123 TestDump('#', lldb::eFormatCharPrintable, "#");
124 TestDump(std::complex<float>(1.2, 3.4), lldb::eFormatComplex, "1.2 + 3.4i");
125 TestDump(std::complex<double>(4.5, 6.7), lldb::eFormatComplex, "4.5 + 6.7i");
127 // long double is not tested here because for some platforms we treat it as 10
128 // bytes when the compiler allocates 16 bytes of space for it. (see
129 // DataExtractor::GetLongDouble) Meaning that when we extract the second one,
130 // it gets the wrong value (it's 6 bytes off). You could manually construct a
131 // set of bytes to match the 10 byte format but then if the test runs on a
132 // machine where we don't use 10 it'll break.
134 // Test printable characters.
135 TestDump(llvm::StringRef("aardvark"), lldb::Format::eFormatCString,
136 "\"aardvark\"");
137 // Test unprintable characters.
138 TestDump(llvm::StringRef("\xcf\xfa\xed\xfe\f"), lldb::Format::eFormatCString,
139 "\"\\xcf\\xfa\\xed\\xfe\\f\"");
140 // Test a mix of printable and unprintable characters.
141 TestDump(llvm::StringRef("\xcf\xfa\ffoo"), lldb::Format::eFormatCString,
142 "\"\\xcf\\xfa\\ffoo\"");
144 TestDump<uint16_t>(99, lldb::Format::eFormatDecimal, "99");
145 // Just prints as a signed integer.
146 TestDump(-1, lldb::Format::eFormatEnum, "-1");
147 TestDump(0xcafef00d, lldb::Format::eFormatHex, "0xcafef00d");
148 TestDump(0xcafef00d, lldb::Format::eFormatHexUppercase, "0xCAFEF00D");
149 TestDump(0.456, lldb::Format::eFormatFloat, "0.45600000000000002");
150 TestDump(9, lldb::Format::eFormatOctal, "011");
151 // Chars packed into an integer.
152 TestDump<uint32_t>(0x4C4C4442, lldb::Format::eFormatOSType, "'LLDB'");
153 // Unicode8 doesn't have a specific formatter.
154 TestDump<uint8_t>(0x34, lldb::Format::eFormatUnicode8, "0x34");
155 TestDump<uint16_t>(0x1122, lldb::Format::eFormatUnicode16, "U+1122");
156 TestDump<uint32_t>(0x12345678, lldb::Format::eFormatUnicode32,
157 "U+0x12345678");
158 TestDump<unsigned int>(654321, lldb::Format::eFormatUnsigned, "654321");
159 // This pointer is printed based on the size of uint64_t, so the test is the
160 // same for 32/64 bit host.
161 TestDump<uint64_t>(0x4444555566667777, lldb::Format::eFormatPointer,
162 "0x4444555566667777");
164 TestDump(std::vector<char>{'A', '\x01', 'C'},
165 lldb::Format::eFormatVectorOfChar, "{A\\x01C}");
166 TestDump(std::vector<int8_t>{0, -1, std::numeric_limits<int8_t>::max()},
167 lldb::Format::eFormatVectorOfSInt8, "{0 -1 127}");
168 TestDump(std::vector<uint8_t>{12, 0xFF, 34},
169 lldb::Format::eFormatVectorOfUInt8, "{0x0c 0xff 0x22}");
170 TestDump(std::vector<int16_t>{-1, 1234, std::numeric_limits<int16_t>::max()},
171 lldb::Format::eFormatVectorOfSInt16, "{-1 1234 32767}");
172 TestDump(std::vector<uint16_t>{0xffff, 0xabcd, 0x1234},
173 lldb::Format::eFormatVectorOfUInt16, "{0xffff 0xabcd 0x1234}");
174 TestDump(std::vector<int32_t>{0, -1, std::numeric_limits<int32_t>::max()},
175 lldb::Format::eFormatVectorOfSInt32, "{0 -1 2147483647}");
176 TestDump(std::vector<uint32_t>{0, 0xffffffff, 0x1234abcd},
177 lldb::Format::eFormatVectorOfUInt32,
178 "{0x00000000 0xffffffff 0x1234abcd}");
179 TestDump(std::vector<int64_t>{0, -1, std::numeric_limits<int64_t>::max()},
180 lldb::Format::eFormatVectorOfSInt64, "{0 -1 9223372036854775807}");
181 TestDump(std::vector<uint64_t>{0, 0xaaaabbbbccccdddd},
182 lldb::Format::eFormatVectorOfUInt64,
183 "{0x0000000000000000 0xaaaabbbbccccdddd}");
185 // See half2float for format details.
186 // Test zeroes.
187 TestDump(std::vector<uint16_t>{0x0000, 0x8000},
188 lldb::Format::eFormatVectorOfFloat16, "{0 -0}");
189 // Some subnormal numbers.
190 TestDump(std::vector<uint16_t>{0x0001, 0x8001},
191 lldb::Format::eFormatVectorOfFloat16, "{5.9605E-8 -5.9605E-8}");
192 // A full mantisse and empty expontent.
193 TestDump(std::vector<uint16_t>{0x83ff, 0x03ff},
194 lldb::Format::eFormatVectorOfFloat16, "{-6.0976E-5 6.0976E-5}");
195 // Some normal numbers.
196 TestDump(std::vector<uint16_t>{0b0100001001001000},
197 lldb::Format::eFormatVectorOfFloat16, "{3.1406}");
198 // Largest and smallest normal number.
199 TestDump(std::vector<uint16_t>{0x0400, 0x7bff},
200 lldb::Format::eFormatVectorOfFloat16, "{6.1035E-5 65504}");
201 TestDump(std::vector<uint16_t>{0xabcd, 0x1234},
202 lldb::Format::eFormatVectorOfFloat16, "{-0.060944 7.5722E-4}");
204 // quiet/signaling NaNs.
205 TestDump(std::vector<uint16_t>{0xffff, 0xffc0, 0x7fff, 0x7fc0},
206 lldb::Format::eFormatVectorOfFloat16, "{NaN NaN NaN NaN}");
207 // +/-Inf.
208 TestDump(std::vector<uint16_t>{0xfc00, 0x7c00},
209 lldb::Format::eFormatVectorOfFloat16, "{-Inf +Inf}");
211 TestDump(std::vector<float>{std::numeric_limits<float>::min(),
212 std::numeric_limits<float>::max()},
213 lldb::Format::eFormatVectorOfFloat32,
214 "{1.17549435E-38 3.40282347E+38}");
215 TestDump(std::vector<float>{std::numeric_limits<float>::quiet_NaN(),
216 std::numeric_limits<float>::signaling_NaN(),
217 -std::numeric_limits<float>::quiet_NaN(),
218 -std::numeric_limits<float>::signaling_NaN()},
219 lldb::Format::eFormatVectorOfFloat32, "{NaN NaN NaN NaN}");
220 TestDump(std::vector<double>{std::numeric_limits<double>::min(),
221 std::numeric_limits<double>::max()},
222 lldb::Format::eFormatVectorOfFloat64,
223 "{2.2250738585072014E-308 1.7976931348623157E+308}");
224 TestDump(
225 std::vector<double>{
226 std::numeric_limits<double>::quiet_NaN(),
227 std::numeric_limits<double>::signaling_NaN(),
228 -std::numeric_limits<double>::quiet_NaN(),
229 -std::numeric_limits<double>::signaling_NaN(),
231 lldb::Format::eFormatVectorOfFloat64, "{NaN NaN NaN NaN}");
233 // Not sure we can rely on having uint128_t everywhere so emulate with
234 // uint64_t.
235 TestDump(
236 std::vector<uint64_t>{0x1, 0x1111222233334444, 0xaaaabbbbccccdddd, 0x0},
237 lldb::Format::eFormatVectorOfUInt128,
238 "{0x11112222333344440000000000000001 "
239 "0x0000000000000000aaaabbbbccccdddd}");
241 TestDump(std::vector<int>{2, 4}, lldb::Format::eFormatComplexInteger,
242 "2 + 4i");
244 // Without an execution context this just prints the pointer on its own.
245 TestDump<uint32_t>(0x11223344, lldb::Format::eFormatAddressInfo,
246 "0x11223344");
248 // Input not written in hex form because that requires C++17.
249 TestDump<float>(10, lldb::Format::eFormatHexFloat, "0x1.4p3");
250 TestDump<double>(10, lldb::Format::eFormatHexFloat, "0x1.4p3");
251 // long double not supported, see ItemByteSizeErrors.
253 // Can't disassemble without an execution context.
254 TestDump<uint32_t>(0xcafef00d, lldb::Format::eFormatInstruction,
255 "invalid target");
257 // Has no special handling, intended for use elsewhere.
258 TestDump<int>(99, lldb::Format::eFormatVoid, "0x00000063");
261 TEST(DumpDataExtractorTest, FormatCharArray) {
262 // Unlike the other formats, charArray isn't 1 array of N chars.
263 // It must be passed as N chars of 1 byte each.
264 // (eFormatVectorOfChar does this swap for you)
265 std::vector<char> data{'A', '\x01', '#'};
266 StreamString result;
267 DataBufferHeap dumpbuffer(&data[0], data.size());
268 DataExtractor extractor(dumpbuffer.GetBytes(), dumpbuffer.GetByteSize(),
269 endian::InlHostByteOrder(), /*addr_size=*/4);
271 DumpDataExtractor(extractor, &result, 0, lldb::Format::eFormatCharArray,
272 /*item_byte_size=*/1,
273 /*item_count=*/data.size(),
274 /*num_per_line=*/data.size(), 0, 0, 0);
275 ASSERT_EQ("0x00000000: A\\x01#", result.GetString());
277 result.Clear();
278 DumpDataExtractor(extractor, &result, 0, lldb::Format::eFormatCharArray, 1,
279 data.size(), 1, 0, 0, 0);
280 // ASSERT macro thinks the split strings are multiple arguments so make a var.
281 const char *expected = "0x00000000: A\n"
282 "0x00000001: \\x01\n"
283 "0x00000002: #";
284 ASSERT_EQ(expected, result.GetString());
287 template <typename T>
288 void TestDumpMultiLine(std::vector<T> data, lldb::Format format,
289 size_t num_per_line, llvm::StringRef expected) {
290 size_t sz_bytes = data.size() * sizeof(T);
291 TestDumpImpl(&data[0], sz_bytes, data.size(), sz_bytes, num_per_line,
292 0x80000000, format, expected);
295 template <typename T>
296 void TestDumpMultiLine(const T *data, size_t num_items, lldb::Format format,
297 size_t num_per_line, llvm::StringRef expected) {
298 TestDumpImpl(data, sizeof(T) * num_items, sizeof(T), num_items, num_per_line,
299 0x80000000, format, expected);
302 TEST(DumpDataExtractorTest, MultiLine) {
303 // A vector counts as 1 item regardless of size.
304 TestDumpMultiLine(std::vector<uint8_t>{0x11},
305 lldb::Format::eFormatVectorOfUInt8, 1,
306 "0x80000000: {0x11}");
307 TestDumpMultiLine(std::vector<uint8_t>{0x11, 0x22},
308 lldb::Format::eFormatVectorOfUInt8, 1,
309 "0x80000000: {0x11 0x22}");
311 // If you have multiple vectors then that's multiple items.
312 // Here we say that these 2 bytes are actually 2 1 byte vectors.
313 const std::vector<uint8_t> vector_data{0x11, 0x22};
314 TestDumpMultiLine(vector_data.data(), 2, lldb::Format::eFormatVectorOfUInt8,
315 1, "0x80000000: {0x11}\n0x80000001: {0x22}");
317 // Single value formats can span multiple lines.
318 const std::vector<uint8_t> bytes{0x11, 0x22, 0x33};
319 const char *expected_bytes_3_line = "0x80000000: 0x11\n"
320 "0x80000001: 0x22\n"
321 "0x80000002: 0x33";
322 TestDumpMultiLine(bytes.data(), bytes.size(), lldb::Format::eFormatHex, 1,
323 expected_bytes_3_line);
325 // Lines may not have the full number of items.
326 TestDumpMultiLine(bytes.data(), bytes.size(), lldb::Format::eFormatHex, 4,
327 "0x80000000: 0x11 0x22 0x33");
328 const char *expected_bytes_2_line = "0x80000000: 0x11 0x22\n"
329 "0x80000002: 0x33";
330 TestDumpMultiLine(bytes.data(), bytes.size(), lldb::Format::eFormatHex, 2,
331 expected_bytes_2_line);
333 // The line address accounts for item sizes other than 1 byte.
334 const std::vector<uint16_t> shorts{0x1111, 0x2222, 0x3333};
335 const char *expected_shorts_2_line = "0x80000000: 0x1111 0x2222\n"
336 "0x80000004: 0x3333";
337 TestDumpMultiLine(shorts.data(), shorts.size(), lldb::Format::eFormatHex, 2,
338 expected_shorts_2_line);
340 // The ascii column is positioned using the maximum line length.
341 const std::vector<char> chars{'L', 'L', 'D', 'B'};
342 const char *expected_chars_2_lines = "0x80000000: 4c 4c 44 LLD\n"
343 "0x80000003: 42 B";
344 TestDumpMultiLine(chars.data(), chars.size(),
345 lldb::Format::eFormatBytesWithASCII, 3,
346 expected_chars_2_lines);
349 void TestDumpWithItemByteSize(size_t item_byte_size, lldb::Format format,
350 llvm::StringRef expected) {
351 // We won't be reading this data so anything will do.
352 uint8_t dummy = 0;
353 TestDumpImpl(&dummy, 1, item_byte_size, 1, 1, LLDB_INVALID_ADDRESS, format,
354 expected);
357 TEST(DumpDataExtractorTest, ItemByteSizeErrors) {
358 TestDumpWithItemByteSize(
359 16, lldb::Format::eFormatBoolean,
360 "error: unsupported byte size (16) for boolean format");
361 TestDumpWithItemByteSize(21, lldb::Format::eFormatChar,
362 "error: unsupported byte size (21) for char format");
363 TestDumpWithItemByteSize(
364 18, lldb::Format::eFormatComplexInteger,
365 "error: unsupported byte size (18) for complex integer format");
367 // The code uses sizeof(long double) for these checks. This changes by host
368 // but we know it won't be >16.
369 TestDumpWithItemByteSize(
370 34, lldb::Format::eFormatComplex,
371 "error: unsupported byte size (34) for complex float format");
372 TestDumpWithItemByteSize(
373 18, lldb::Format::eFormatFloat,
374 "error: unsupported byte size (18) for float format");
376 // We want sizes to exactly match one of float/double.
377 TestDumpWithItemByteSize(
378 14, lldb::Format::eFormatComplex,
379 "error: unsupported byte size (14) for complex float format");
380 TestDumpWithItemByteSize(3, lldb::Format::eFormatFloat,
381 "error: unsupported byte size (3) for float format");
383 // We only allow float and double size.
384 TestDumpWithItemByteSize(
385 1, lldb::Format::eFormatHexFloat,
386 "error: unsupported byte size (1) for hex float format");
387 TestDumpWithItemByteSize(
388 17, lldb::Format::eFormatHexFloat,
389 "error: unsupported byte size (17) for hex float format");