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 | |
13 | using namespace lldb_private; |
14 | |
15 | TEST(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 | |
54 | TEST(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 | |
70 | TEST(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 | |
79 | TEST(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 | |
88 | TEST(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 | |
97 | TEST(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 | |
106 | TEST(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 | |
115 | TEST(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 | |
148 | TEST(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 | |
189 | TEST(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 | |
224 | TEST(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 | |
265 | TEST(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 | |
284 | TEST(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 | |
303 | TEST(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 | |
327 | TEST(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 | |
351 | TEST(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 | |
378 | TEST(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 | |