404 lines · cpp
1//===-- DataExtractorTest.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 "gtest/gtest.h"10 11#include "lldb/Utility/DataExtractor.h"12 13using namespace lldb_private;14 15TEST(DataExtractorTest, GetBitfield) {16 uint8_t buffer[] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF};17 DataExtractor LE(buffer, sizeof(buffer), lldb::eByteOrderLittle,18 sizeof(void *));19 DataExtractor BE(buffer, sizeof(buffer), lldb::eByteOrderBig, sizeof(void *));20 21 lldb::offset_t offset;22 23 offset = 0;24 ASSERT_EQ(buffer[1], LE.GetMaxU64Bitfield(&offset, sizeof(buffer), 8, 8));25 offset = 0;26 ASSERT_EQ(buffer[1], BE.GetMaxU64Bitfield(&offset, sizeof(buffer), 8, 8));27 offset = 0;28 ASSERT_EQ(static_cast<uint64_t>(0xEFCDAB8967452301),29 LE.GetMaxU64Bitfield(&offset, sizeof(buffer), 64, 0));30 offset = 0;31 ASSERT_EQ(static_cast<uint64_t>(0x0123456789ABCDEF),32 BE.GetMaxU64Bitfield(&offset, sizeof(buffer), 64, 0));33 offset = 0;34 ASSERT_EQ(static_cast<uint64_t>(0x01234567),35 BE.GetMaxU64Bitfield(&offset, sizeof(buffer), 32, 0));36 offset = 0;37 ASSERT_EQ(static_cast<uint64_t>(0x012345678),38 BE.GetMaxU64Bitfield(&offset, sizeof(buffer), 36, 0));39 40 offset = 0;41 ASSERT_EQ(int8_t(buffer[1]),42 LE.GetMaxS64Bitfield(&offset, sizeof(buffer), 8, 8));43 offset = 0;44 ASSERT_EQ(int8_t(buffer[1]),45 BE.GetMaxS64Bitfield(&offset, sizeof(buffer), 8, 8));46 offset = 0;47 ASSERT_EQ(static_cast<int64_t>(0xEFCDAB8967452301),48 LE.GetMaxS64Bitfield(&offset, sizeof(buffer), 64, 0));49 offset = 0;50 ASSERT_EQ(static_cast<int64_t>(0x0123456789ABCDEF),51 BE.GetMaxS64Bitfield(&offset, sizeof(buffer), 64, 0));52}53 54TEST(DataExtractorTest, PeekData) {55 uint8_t buffer[] = {0x01, 0x02, 0x03, 0x04};56 DataExtractor E(buffer, sizeof buffer, lldb::eByteOrderLittle, 4);57 58 EXPECT_EQ(buffer + 0, E.PeekData(0, 0));59 EXPECT_EQ(buffer + 0, E.PeekData(0, 4));60 EXPECT_EQ(nullptr, E.PeekData(0, 5));61 62 EXPECT_EQ(buffer + 2, E.PeekData(2, 0));63 EXPECT_EQ(buffer + 2, E.PeekData(2, 2));64 EXPECT_EQ(nullptr, E.PeekData(2, 3));65 66 EXPECT_EQ(buffer + 4, E.PeekData(4, 0));67 EXPECT_EQ(nullptr, E.PeekData(4, 1));68}69 70TEST(DataExtractorTest, GetCStr) {71 uint8_t buffer[] = {'X', 'f', 'o', 'o', '\0'};72 DataExtractor E(buffer, sizeof buffer, lldb::eByteOrderLittle, 4);73 74 lldb::offset_t offset = 1;75 EXPECT_STREQ("foo", E.GetCStr(&offset));76 EXPECT_EQ(5U, offset);77}78 79TEST(DataExtractorTest, GetCStrEmpty) {80 uint8_t buffer[] = {'X', '\0'};81 DataExtractor E(buffer, sizeof buffer, lldb::eByteOrderLittle, 4);82 83 lldb::offset_t offset = 1;84 EXPECT_STREQ("", E.GetCStr(&offset));85 EXPECT_EQ(2U, offset);86}87 88TEST(DataExtractorTest, GetCStrUnterminated) {89 uint8_t buffer[] = {'X', 'f', 'o', 'o'};90 DataExtractor E(buffer, sizeof buffer, lldb::eByteOrderLittle, 4);91 92 lldb::offset_t offset = 1;93 EXPECT_EQ(nullptr, E.GetCStr(&offset));94 EXPECT_EQ(1U, offset);95}96 97TEST(DataExtractorTest, GetCStrAtEnd) {98 uint8_t buffer[] = {'X'};99 DataExtractor E(buffer, sizeof buffer, lldb::eByteOrderLittle, 4);100 101 lldb::offset_t offset = 1;102 EXPECT_EQ(nullptr, E.GetCStr(&offset));103 EXPECT_EQ(1U, offset);104}105 106TEST(DataExtractorTest, GetCStrAtNullOffset) {107 uint8_t buffer[] = {'f', 'o', 'o', '\0'};108 DataExtractor E(buffer, sizeof buffer, lldb::eByteOrderLittle, 4);109 110 lldb::offset_t offset = 0;111 EXPECT_STREQ("foo", E.GetCStr(&offset));112 EXPECT_EQ(4U, offset);113}114 115TEST(DataExtractorTest, UncommonAddressSize) {116 uint8_t buffer[] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08};117 DataExtractor E2(buffer, sizeof buffer, lldb::eByteOrderLittle, 2);118 DataExtractor E5(buffer, sizeof buffer, lldb::eByteOrderLittle, 5);119 DataExtractor E7(buffer, sizeof buffer, lldb::eByteOrderLittle, 7);120 121 lldb::offset_t offset;122 123 // Test 2-byte addresses (for AVR).124 offset = 0;125 EXPECT_EQ(0x0201U, E2.GetMaxU64(&offset, 2));126 EXPECT_EQ(2U, offset);127 offset = 0;128 EXPECT_EQ(0x0201U, E2.GetAddress(&offset));129 EXPECT_EQ(2U, offset);130 131 // Test 5-byte addresses.132 offset = 0;133 EXPECT_EQ(0x030201U, E5.GetMaxU64(&offset, 3));134 EXPECT_EQ(3U, offset);135 offset = 3;136 EXPECT_EQ(0x0807060504U, E5.GetAddress(&offset));137 EXPECT_EQ(8U, offset);138 139 // Test 7-byte addresses.140 offset = 0;141 EXPECT_EQ(0x0504030201U, E7.GetMaxU64(&offset, 5));142 EXPECT_EQ(5U, offset);143 offset = 0;144 EXPECT_EQ(0x07060504030201U, E7.GetAddress(&offset));145 EXPECT_EQ(7U, offset);146}147 148TEST(DataExtractorTest, GetMaxU64) {149 uint8_t buffer[] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08};150 DataExtractor LE(buffer, sizeof(buffer), lldb::eByteOrderLittle,151 sizeof(void *));152 DataExtractor BE(buffer, sizeof(buffer), lldb::eByteOrderBig, sizeof(void *));153 154 lldb::offset_t offset;155 156 // Check with the minimum allowed byte size.157 offset = 0;158 EXPECT_EQ(0x01U, LE.GetMaxU64(&offset, 1));159 EXPECT_EQ(1U, offset);160 offset = 0;161 EXPECT_EQ(0x01U, BE.GetMaxU64(&offset, 1));162 EXPECT_EQ(1U, offset);163 164 // Check with a non-zero offset.165 offset = 1;166 EXPECT_EQ(0x0302U, LE.GetMaxU64(&offset, 2));167 EXPECT_EQ(3U, offset);168 offset = 1;169 EXPECT_EQ(0x0203U, BE.GetMaxU64(&offset, 2));170 EXPECT_EQ(3U, offset);171 172 // Check with the byte size not being a multiple of 2.173 offset = 0;174 EXPECT_EQ(0x07060504030201U, LE.GetMaxU64(&offset, 7));175 EXPECT_EQ(7U, offset);176 offset = 0;177 EXPECT_EQ(0x01020304050607U, BE.GetMaxU64(&offset, 7));178 EXPECT_EQ(7U, offset);179 180 // Check with the maximum allowed byte size.181 offset = 0;182 EXPECT_EQ(0x0807060504030201U, LE.GetMaxU64(&offset, 8));183 EXPECT_EQ(8U, offset);184 offset = 0;185 EXPECT_EQ(0x0102030405060708U, BE.GetMaxU64(&offset, 8));186 EXPECT_EQ(8U, offset);187}188 189TEST(DataExtractorTest, GetMaxS64) {190 uint8_t buffer[] = {0x01, 0x02, 0x83, 0x04, 0x05, 0x06, 0x07, 0x08};191 DataExtractor LE(buffer, sizeof(buffer), lldb::eByteOrderLittle,192 sizeof(void *));193 DataExtractor BE(buffer, sizeof(buffer), lldb::eByteOrderBig, sizeof(void *));194 195 lldb::offset_t offset;196 197 // Check with the minimum allowed byte size.198 offset = 0;199 EXPECT_EQ(0x01, LE.GetMaxS64(&offset, 1));200 EXPECT_EQ(1U, offset);201 offset = 0;202 EXPECT_EQ(0x01, BE.GetMaxS64(&offset, 1));203 EXPECT_EQ(1U, offset);204 205 // Check that sign extension works correctly.206 offset = 0;207 int64_t value = LE.GetMaxS64(&offset, 3);208 EXPECT_EQ(0xffffffffff830201U, *reinterpret_cast<uint64_t *>(&value));209 EXPECT_EQ(3U, offset);210 offset = 2;211 value = BE.GetMaxS64(&offset, 3);212 EXPECT_EQ(0xffffffffff830405U, *reinterpret_cast<uint64_t *>(&value));213 EXPECT_EQ(5U, offset);214 215 // Check with the maximum allowed byte size.216 offset = 0;217 EXPECT_EQ(0x0807060504830201, LE.GetMaxS64(&offset, 8));218 EXPECT_EQ(8U, offset);219 offset = 0;220 EXPECT_EQ(0x0102830405060708, BE.GetMaxS64(&offset, 8));221 EXPECT_EQ(8U, offset);222}223 224TEST(DataExtractorTest, GetMaxU64_unchecked) {225 uint8_t buffer[] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08};226 DataExtractor LE(buffer, sizeof(buffer), lldb::eByteOrderLittle,227 sizeof(void *));228 DataExtractor BE(buffer, sizeof(buffer), lldb::eByteOrderBig, sizeof(void *));229 230 lldb::offset_t offset;231 232 // Check with the minimum allowed byte size.233 offset = 0;234 EXPECT_EQ(0x01U, LE.GetMaxU64_unchecked(&offset, 1));235 EXPECT_EQ(1U, offset);236 offset = 0;237 EXPECT_EQ(0x01U, BE.GetMaxU64_unchecked(&offset, 1));238 EXPECT_EQ(1U, offset);239 240 // Check with a non-zero offset.241 offset = 1;242 EXPECT_EQ(0x0302U, LE.GetMaxU64_unchecked(&offset, 2));243 EXPECT_EQ(3U, offset);244 offset = 1;245 EXPECT_EQ(0x0203U, BE.GetMaxU64_unchecked(&offset, 2));246 EXPECT_EQ(3U, offset);247 248 // Check with the byte size not being a multiple of 2.249 offset = 0;250 EXPECT_EQ(0x07060504030201U, LE.GetMaxU64_unchecked(&offset, 7));251 EXPECT_EQ(7U, offset);252 offset = 0;253 EXPECT_EQ(0x01020304050607U, BE.GetMaxU64_unchecked(&offset, 7));254 EXPECT_EQ(7U, offset);255 256 // Check with the maximum allowed byte size.257 offset = 0;258 EXPECT_EQ(0x0807060504030201U, LE.GetMaxU64_unchecked(&offset, 8));259 EXPECT_EQ(8U, offset);260 offset = 0;261 EXPECT_EQ(0x0102030405060708U, BE.GetMaxU64_unchecked(&offset, 8));262 EXPECT_EQ(8U, offset);263}264 265TEST(DataExtractorTest, GetSLEB128_bit63) {266 uint8_t buffer[] = {0xff, 0x80, 0xff, 0x80, 0xff, 0x80, 0xff, 0x80, 0x7f};267 268 DataExtractor LE(buffer, sizeof(buffer), lldb::eByteOrderLittle,269 sizeof(void *));270 DataExtractor BE(buffer, sizeof(buffer), lldb::eByteOrderBig, sizeof(void *));271 272 lldb::offset_t offset;273 274 int64_t expected =275 0b1111111100000001111111000000011111110000000111111100000001111111;276 offset = 0;277 EXPECT_EQ(expected, LE.GetSLEB128(&offset));278 EXPECT_EQ(9U, offset);279 offset = 0;280 EXPECT_EQ(expected, BE.GetSLEB128(&offset));281 EXPECT_EQ(9U, offset);282}283 284TEST(DataExtractorTest, GetULEB128_bit63) {285 uint8_t buffer[] = {0xff, 0x80, 0xff, 0x80, 0xff, 0x80, 0xff, 0x80, 0x7f};286 287 DataExtractor LE(buffer, sizeof(buffer), lldb::eByteOrderLittle,288 sizeof(void *));289 DataExtractor BE(buffer, sizeof(buffer), lldb::eByteOrderBig, sizeof(void *));290 291 lldb::offset_t offset;292 293 uint64_t expected =294 0b0111111100000001111111000000011111110000000111111100000001111111;295 offset = 0;296 EXPECT_EQ(expected, LE.GetULEB128(&offset));297 EXPECT_EQ(9U, offset);298 offset = 0;299 EXPECT_EQ(expected, BE.GetULEB128(&offset));300 EXPECT_EQ(9U, offset);301}302 303TEST(DataExtractorTest, GetFloat) {304 float expected = 4.0f;305 lldb::offset_t offset;306 307 {308 uint8_t buffer[] = {0x00, 0x00, 0x80, 0x40};309 DataExtractor LE(buffer, sizeof(buffer), lldb::eByteOrderLittle,310 sizeof(void *));311 312 offset = 0;313 EXPECT_DOUBLE_EQ(expected, LE.GetFloat(&offset));314 EXPECT_EQ(4U, offset);315 }316 317 {318 uint8_t buffer[] = {0x40, 0x80, 0x00, 0x00};319 DataExtractor BE(buffer, sizeof(buffer), lldb::eByteOrderBig,320 sizeof(void *));321 offset = 0;322 EXPECT_DOUBLE_EQ(expected, BE.GetFloat(&offset));323 EXPECT_EQ(4U, offset);324 }325}326 327TEST(DataExtractorTest, GetFloatUnaligned) {328 float expected = 4.0f;329 lldb::offset_t offset;330 331 {332 uint8_t buffer[] = {0x00, 0x00, 0x00, 0x80, 0x40};333 DataExtractor LE(buffer, sizeof(buffer), lldb::eByteOrderLittle,334 sizeof(void *));335 336 offset = 1;337 EXPECT_DOUBLE_EQ(expected, LE.GetFloat(&offset));338 EXPECT_EQ(5U, offset);339 }340 341 {342 uint8_t buffer[] = {0x00, 0x40, 0x80, 0x00, 0x00};343 DataExtractor BE(buffer, sizeof(buffer), lldb::eByteOrderBig,344 sizeof(void *));345 offset = 1;346 EXPECT_DOUBLE_EQ(expected, BE.GetFloat(&offset));347 EXPECT_EQ(5U, offset);348 }349}350 351TEST(DataExtractorTest, GetDouble) {352 if (sizeof(double) != 8)353 return;354 355 double expected = 4.0f;356 lldb::offset_t offset;357 358 {359 uint8_t buffer[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x40};360 DataExtractor LE(buffer, sizeof(buffer), lldb::eByteOrderLittle,361 sizeof(void *));362 363 offset = 0;364 EXPECT_DOUBLE_EQ(expected, LE.GetDouble(&offset));365 EXPECT_EQ(8U, offset);366 }367 368 {369 uint8_t buffer[] = {0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};370 DataExtractor BE(buffer, sizeof(buffer), lldb::eByteOrderBig,371 sizeof(void *));372 offset = 0;373 EXPECT_DOUBLE_EQ(expected, BE.GetDouble(&offset));374 EXPECT_EQ(8U, offset);375 }376}377 378TEST(DataExtractorTest, GetDoubleUnaligned) {379 if (sizeof(double) != 8)380 return;381 382 float expected = 4.0f;383 lldb::offset_t offset;384 385 {386 uint8_t buffer[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x40};387 DataExtractor LE(buffer, sizeof(buffer), lldb::eByteOrderLittle,388 sizeof(void *));389 390 offset = 1;391 EXPECT_DOUBLE_EQ(expected, LE.GetDouble(&offset));392 EXPECT_EQ(9U, offset);393 }394 395 {396 uint8_t buffer[] = {0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};397 DataExtractor BE(buffer, sizeof(buffer), lldb::eByteOrderBig,398 sizeof(void *));399 offset = 1;400 EXPECT_DOUBLE_EQ(expected, BE.GetDouble(&offset));401 EXPECT_EQ(9U, offset);402 }403}404