brintos

brintos / llvm-project-archived public Read only

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