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-exception
6//
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_ptr: &offset, byte_size: 3);
208 EXPECT_EQ(0xffffffffff830201U, *reinterpret_cast<uint64_t *>(&value));
209 EXPECT_EQ(3U, offset);
210 offset = 2;
211 value = BE.GetMaxS64(offset_ptr: &offset, byte_size: 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

source code of lldb/unittests/Utility/DataExtractorTest.cpp