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 //===----------------------------------------------------------------------===// 8 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 17 using namespace lldb; 18 using namespace lldb_private; 19 20 static void test_format_impl(const void *data, size_t data_size, 21 size_t item_count, lldb::Format format, 22 llvm::StringRef expected) { 23 StreamString result; 24 DataBufferHeap dumpbuffer(data, data_size); 25 DataExtractor extractor(dumpbuffer.GetBytes(), dumpbuffer.GetByteSize(), 26 endian::InlHostByteOrder(), 27 /*addr_size=*/4); 28 DumpDataExtractor(extractor, &result, 0, format, data_size, item_count, 1, 0, 29 0, 0); 30 ASSERT_EQ(expected, result.GetString()); 31 } 32 33 template <typename T> 34 static void test_format(T data, lldb::Format format, llvm::StringRef expected) { 35 test_format_impl(&data, sizeof(T), 1, format, expected); 36 } 37 38 static void test_format(llvm::StringRef str, lldb::Format format, 39 llvm::StringRef expected) { 40 test_format_impl(str.bytes_begin(), 41 // +1 to include the NULL char as the last byte 42 str.size() + 1, 1, format, expected); 43 } 44 45 template <typename T> 46 static void test_format(const std::vector<T> data, lldb::Format format, 47 llvm::StringRef expected) { 48 test_format_impl(&data[0], data.size() * sizeof(T), data.size(), format, 49 expected); 50 } 51 52 TEST(DumpDataExtractorTest, Formats) { 53 test_format<uint8_t>(1, lldb::eFormatDefault, "0x00000000: 0x01"); 54 test_format<uint8_t>(1, lldb::eFormatBoolean, "0x00000000: true"); 55 test_format<uint8_t>(0xAA, lldb::eFormatBinary, "0x00000000: 0b10101010"); 56 test_format<uint8_t>(1, lldb::eFormatBytes, "0x00000000: 01"); 57 test_format<uint8_t>(1, lldb::eFormatBytesWithASCII, "0x00000000: 01 ."); 58 test_format('?', lldb::eFormatChar, "0x00000000: '?'"); 59 test_format('\x1A', lldb::eFormatCharPrintable, "0x00000000: ."); 60 test_format('#', lldb::eFormatCharPrintable, "0x00000000: #"); 61 test_format(std::complex<float>(1.2, 3.4), lldb::eFormatComplex, 62 "0x00000000: 1.2 + 3.4i"); 63 test_format(std::complex<double>(4.5, 6.7), lldb::eFormatComplex, 64 "0x00000000: 4.5 + 6.7i"); 65 66 // long double is not tested here because for some platforms we treat it as 10 67 // bytes when the compiler allocates 16 bytes of space for it. (see 68 // DataExtractor::GetLongDouble) Meaning that when we extract the second one, 69 // it gets the wrong value (it's 6 bytes off). You could manually construct a 70 // set of bytes to match the 10 byte format but then if the test runs on a 71 // machine where we don't use 10 it'll break. 72 73 test_format(llvm::StringRef("aardvark"), lldb::Format::eFormatCString, 74 "0x00000000: \"aardvark\""); 75 test_format<uint16_t>(99, lldb::Format::eFormatDecimal, "0x00000000: 99"); 76 // Just prints as a signed integer. 77 test_format(-1, lldb::Format::eFormatEnum, "0x00000000: -1"); 78 test_format(0xcafef00d, lldb::Format::eFormatHex, "0x00000000: 0xcafef00d"); 79 test_format(0xcafef00d, lldb::Format::eFormatHexUppercase, 80 "0x00000000: 0xCAFEF00D"); 81 test_format(0.456, lldb::Format::eFormatFloat, "0x00000000: 0.456"); 82 test_format(9, lldb::Format::eFormatOctal, "0x00000000: 011"); 83 // Chars packed into an integer. 84 test_format<uint32_t>(0x4C4C4442, lldb::Format::eFormatOSType, 85 "0x00000000: 'LLDB'"); 86 // Unicode8 doesn't have a specific formatter. 87 test_format<uint8_t>(0x34, lldb::Format::eFormatUnicode8, "0x00000000: 0x34"); 88 test_format<uint16_t>(0x1122, lldb::Format::eFormatUnicode16, 89 "0x00000000: U+1122"); 90 test_format<uint32_t>(0x12345678, lldb::Format::eFormatUnicode32, 91 "0x00000000: U+0x12345678"); 92 test_format<unsigned int>(654321, lldb::Format::eFormatUnsigned, 93 "0x00000000: 654321"); 94 // This pointer is printed based on the size of uint64_t, so the test is the 95 // same for 32/64 bit host. 96 test_format<uint64_t>(0x4444555566667777, lldb::Format::eFormatPointer, 97 "0x00000000: 0x4444555566667777"); 98 99 test_format(std::vector<char>{'A', '\x01', 'C'}, 100 lldb::Format::eFormatVectorOfChar, "0x00000000: {A\\x01C}"); 101 test_format(std::vector<int8_t>{0, -1, std::numeric_limits<int8_t>::max()}, 102 lldb::Format::eFormatVectorOfSInt8, "0x00000000: {0 -1 127}"); 103 test_format(std::vector<uint8_t>{12, 0xFF, 34}, 104 lldb::Format::eFormatVectorOfUInt8, 105 "0x00000000: {0x0c 0xff 0x22}"); 106 test_format( 107 std::vector<int16_t>{-1, 1234, std::numeric_limits<int16_t>::max()}, 108 lldb::Format::eFormatVectorOfSInt16, "0x00000000: {-1 1234 32767}"); 109 test_format(std::vector<uint16_t>{0xffff, 0xabcd, 0x1234}, 110 lldb::Format::eFormatVectorOfUInt16, 111 "0x00000000: {0xffff 0xabcd 0x1234}"); 112 test_format(std::vector<int32_t>{0, -1, std::numeric_limits<int32_t>::max()}, 113 lldb::Format::eFormatVectorOfSInt32, 114 "0x00000000: {0 -1 2147483647}"); 115 test_format(std::vector<uint32_t>{0, 0xffffffff, 0x1234abcd}, 116 lldb::Format::eFormatVectorOfUInt32, 117 "0x00000000: {0x00000000 0xffffffff 0x1234abcd}"); 118 test_format(std::vector<int64_t>{0, -1, std::numeric_limits<int64_t>::max()}, 119 lldb::Format::eFormatVectorOfSInt64, 120 "0x00000000: {0 -1 9223372036854775807}"); 121 test_format(std::vector<uint64_t>{0, 0xaaaabbbbccccdddd}, 122 lldb::Format::eFormatVectorOfUInt64, 123 "0x00000000: {0x0000000000000000 0xaaaabbbbccccdddd}"); 124 125 // See half2float for format details. 126 test_format(std::vector<uint16_t>{0xabcd, 0x1234}, 127 lldb::Format::eFormatVectorOfFloat16, 128 "0x00000000: {-0.0609436 0.000757217}"); 129 test_format(std::vector<float>{std::numeric_limits<float>::min(), 130 std::numeric_limits<float>::max()}, 131 lldb::Format::eFormatVectorOfFloat32, 132 "0x00000000: {1.17549e-38 3.40282e+38}"); 133 test_format(std::vector<double>{std::numeric_limits<double>::min(), 134 std::numeric_limits<double>::max()}, 135 lldb::Format::eFormatVectorOfFloat64, 136 "0x00000000: {2.2250738585072e-308 1.79769313486232e+308}"); 137 138 // Not sure we can rely on having uint128_t everywhere so emulate with 139 // uint64_t. 140 test_format( 141 std::vector<uint64_t>{0x1, 0x1111222233334444, 0xaaaabbbbccccdddd, 0x0}, 142 lldb::Format::eFormatVectorOfUInt128, 143 "0x00000000: {0x11112222333344440000000000000001 " 144 "0x0000000000000000aaaabbbbccccdddd}"); 145 146 test_format(std::vector<int>{2, 4}, lldb::Format::eFormatComplexInteger, 147 "0x00000000: 2 + 4i"); 148 149 // Without an execution context this just prints the pointer on its own. 150 test_format<uint32_t>(0x11223344, lldb::Format::eFormatAddressInfo, 151 "0x00000000: 0x11223344"); 152 153 // Input not written in hex form because that requires C++17. 154 test_format<float>(10, lldb::Format::eFormatHexFloat, "0x00000000: 0x1.4p3"); 155 156 // Can't disassemble without an execution context. 157 test_format<uint32_t>(0xcafef00d, lldb::Format::eFormatInstruction, 158 "invalid target"); 159 160 // Has no special handling, intended for use elsewhere. 161 test_format<int>(99, lldb::Format::eFormatVoid, "0x00000000: 0x00000063"); 162 } 163 164 TEST(DumpDataExtractorTest, FormatCharArray) { 165 // Unlike the other formats, charArray isn't 1 array of N chars. 166 // It must be passed as N chars of 1 byte each. 167 // (eFormatVectorOfChar does this swap for you) 168 std::vector<char> data{'A', '\x01', '#'}; 169 StreamString result; 170 DataBufferHeap dumpbuffer(&data[0], data.size()); 171 DataExtractor extractor(dumpbuffer.GetBytes(), dumpbuffer.GetByteSize(), 172 endian::InlHostByteOrder(), /*addr_size=*/4); 173 174 DumpDataExtractor(extractor, &result, 0, lldb::Format::eFormatCharArray, 175 /*item_byte_size=*/1, 176 /*item_count=*/data.size(), 177 /*num_per_line=*/data.size(), 0, 0, 0); 178 ASSERT_EQ("0x00000000: A\\x01#", result.GetString()); 179 180 result.Clear(); 181 DumpDataExtractor(extractor, &result, 0, lldb::Format::eFormatCharArray, 1, 182 data.size(), 1, 0, 0, 0); 183 // ASSERT macro thinks the split strings are multiple arguments so make a var. 184 const char *expected = "0x00000000: A\n" 185 "0x00000001: \\x01\n" 186 "0x00000002: #"; 187 ASSERT_EQ(expected, result.GetString()); 188 } 189