llvm.org GIT mirror llvm / 8c74f7f
Add the DataExtractor utility class. It is an endian-aware helper that can read data from a StringRef. It will come in handy for DWARF parsing. This class is inspired by LLDB's DataExtractor, but is stripped down to the bare minimum needed for DWARF. Comes with unit tests! git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@139626 91177308-0d34-0410-b5e6-96231b3b80d8 Benjamin Kramer 9 years ago
4 changed file(s) with 639 addition(s) and 0 deletion(s). Raw diff Collapse all Expand all
0 //===-- DataExtractor.h -----------------------------------------*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8
9 #ifndef LLVM_SUPPORT_DATAEXTRACTOR_H
10 #define LLVM_SUPPORT_DATAEXTRACTOR_H
11
12 #include "llvm/ADT/StringRef.h"
13 #include "llvm/Support/DataTypes.h"
14
15 namespace llvm {
16 class DataExtractor {
17 StringRef Data;
18 uint8_t IsLittleEndian;
19 uint8_t PointerSize;
20 public:
21 /// Construct with a buffer that is owned by the caller.
22 ///
23 /// This constructor allows us to use data that is owned by the
24 /// caller. The data must stay around as long as this object is
25 /// valid.
26 DataExtractor(StringRef Data, bool IsLittleEndian, uint8_t PointerSize)
27 : Data(Data), IsLittleEndian(IsLittleEndian), PointerSize(PointerSize) {}
28
29 /// getData - Get the data pointed to by this extractor.
30 StringRef getData() const { return Data; }
31 /// isLittleEndian - Get the endianess for this extractor.
32 bool isLittleEndian() const { return IsLittleEndian; }
33 /// getAddressSize - Get the address size for this extractor.
34 uint8_t getAddressSize() const { return PointerSize; }
35
36 /// Extract a C string from \a *offset_ptr.
37 ///
38 /// Returns a pointer to a C String from the data at the offset
39 /// pointed to by \a offset_ptr. A variable length NULL terminated C
40 /// string will be extracted and the \a offset_ptr will be
41 /// updated with the offset of the byte that follows the NULL
42 /// terminator byte.
43 ///
44 /// @param[in,out] offset_ptr
45 /// A pointer to an offset within the data that will be advanced
46 /// by the appropriate number of bytes if the value is extracted
47 /// correctly. If the offset is out of bounds or there are not
48 /// enough bytes to extract this value, the offset will be left
49 /// unmodified.
50 ///
51 /// @return
52 /// A pointer to the C string value in the data. If the offset
53 /// pointed to by \a offset_ptr is out of bounds, or if the
54 /// offset plus the length of the C string is out of bounds,
55 /// NULL will be returned.
56 const char *getCStr(uint32_t *offset_ptr) const;
57
58 /// Extract an unsigned integer of size \a byte_size from \a
59 /// *offset_ptr.
60 ///
61 /// Extract a single unsigned integer value and update the offset
62 /// pointed to by \a offset_ptr. The size of the extracted integer
63 /// is specified by the \a byte_size argument. \a byte_size should
64 /// have a value greater than or equal to one and less than or equal
65 /// to eight since the return value is 64 bits wide. Any
66 /// \a byte_size values less than 1 or greater than 8 will result in
67 /// nothing being extracted, and zero being returned.
68 ///
69 /// @param[in,out] offset_ptr
70 /// A pointer to an offset within the data that will be advanced
71 /// by the appropriate number of bytes if the value is extracted
72 /// correctly. If the offset is out of bounds or there are not
73 /// enough bytes to extract this value, the offset will be left
74 /// unmodified.
75 ///
76 /// @param[in] byte_size
77 /// The size in byte of the integer to extract.
78 ///
79 /// @return
80 /// The unsigned integer value that was extracted, or zero on
81 /// failure.
82 uint64_t getUnsigned(uint32_t *offset_ptr, uint32_t byte_size) const;
83
84 /// Extract an signed integer of size \a byte_size from \a *offset_ptr.
85 ///
86 /// Extract a single signed integer value (sign extending if required)
87 /// and update the offset pointed to by \a offset_ptr. The size of
88 /// the extracted integer is specified by the \a byte_size argument.
89 /// \a byte_size should have a value greater than or equal to one
90 /// and less than or equal to eight since the return value is 64
91 /// bits wide. Any \a byte_size values less than 1 or greater than
92 /// 8 will result in nothing being extracted, and zero being returned.
93 ///
94 /// @param[in,out] offset_ptr
95 /// A pointer to an offset within the data that will be advanced
96 /// by the appropriate number of bytes if the value is extracted
97 /// correctly. If the offset is out of bounds or there are not
98 /// enough bytes to extract this value, the offset will be left
99 /// unmodified.
100 ///
101 /// @param[in] byte_size
102 /// The size in byte of the integer to extract.
103 ///
104 /// @return
105 /// The sign extended signed integer value that was extracted,
106 /// or zero on failure.
107 int64_t getSigned(uint32_t *offset_ptr, uint32_t size) const;
108
109 //------------------------------------------------------------------
110 /// Extract an pointer from \a *offset_ptr.
111 ///
112 /// Extract a single pointer from the data and update the offset
113 /// pointed to by \a offset_ptr. The size of the extracted pointer
114 /// comes from the \a m_addr_size member variable and should be
115 /// set correctly prior to extracting any pointer values.
116 ///
117 /// @param[in,out] offset_ptr
118 /// A pointer to an offset within the data that will be advanced
119 /// by the appropriate number of bytes if the value is extracted
120 /// correctly. If the offset is out of bounds or there are not
121 /// enough bytes to extract this value, the offset will be left
122 /// unmodified.
123 ///
124 /// @return
125 /// The extracted pointer value as a 64 integer.
126 uint64_t getAddress(uint32_t *offset_ptr) const {
127 return getUnsigned(offset_ptr, PointerSize);
128 }
129
130 /// Extract a uint8_t value from \a *offset_ptr.
131 ///
132 /// Extract a single uint8_t from the binary data at the offset
133 /// pointed to by \a offset_ptr, and advance the offset on success.
134 ///
135 /// @param[in,out] offset_ptr
136 /// A pointer to an offset within the data that will be advanced
137 /// by the appropriate number of bytes if the value is extracted
138 /// correctly. If the offset is out of bounds or there are not
139 /// enough bytes to extract this value, the offset will be left
140 /// unmodified.
141 ///
142 /// @return
143 /// The extracted uint8_t value.
144 uint8_t getU8(uint32_t *offset_ptr) const;
145
146 /// Extract \a count uint8_t values from \a *offset_ptr.
147 ///
148 /// Extract \a count uint8_t values from the binary data at the
149 /// offset pointed to by \a offset_ptr, and advance the offset on
150 /// success. The extracted values are copied into \a dst.
151 ///
152 /// @param[in,out] offset_ptr
153 /// A pointer to an offset within the data that will be advanced
154 /// by the appropriate number of bytes if the value is extracted
155 /// correctly. If the offset is out of bounds or there are not
156 /// enough bytes to extract this value, the offset will be left
157 /// unmodified.
158 ///
159 /// @param[out] dst
160 /// A buffer to copy \a count uint8_t values into. \a dst must
161 /// be large enough to hold all requested data.
162 ///
163 /// @param[in] count
164 /// The number of uint8_t values to extract.
165 ///
166 /// @return
167 /// \a dst if all values were properly extracted and copied,
168 /// NULL otherise.
169 uint8_t *getU8(uint32_t *offset_ptr, uint8_t *dst, uint32_t count) const;
170
171 //------------------------------------------------------------------
172 /// Extract a uint16_t value from \a *offset_ptr.
173 ///
174 /// Extract a single uint16_t from the binary data at the offset
175 /// pointed to by \a offset_ptr, and update the offset on success.
176 ///
177 /// @param[in,out] offset_ptr
178 /// A pointer to an offset within the data that will be advanced
179 /// by the appropriate number of bytes if the value is extracted
180 /// correctly. If the offset is out of bounds or there are not
181 /// enough bytes to extract this value, the offset will be left
182 /// unmodified.
183 ///
184 /// @return
185 /// The extracted uint16_t value.
186 //------------------------------------------------------------------
187 uint16_t getU16(uint32_t *offset_ptr) const;
188
189 /// Extract \a count uint16_t values from \a *offset_ptr.
190 ///
191 /// Extract \a count uint16_t values from the binary data at the
192 /// offset pointed to by \a offset_ptr, and advance the offset on
193 /// success. The extracted values are copied into \a dst.
194 ///
195 /// @param[in,out] offset_ptr
196 /// A pointer to an offset within the data that will be advanced
197 /// by the appropriate number of bytes if the value is extracted
198 /// correctly. If the offset is out of bounds or there are not
199 /// enough bytes to extract this value, the offset will be left
200 /// unmodified.
201 ///
202 /// @param[out] dst
203 /// A buffer to copy \a count uint16_t values into. \a dst must
204 /// be large enough to hold all requested data.
205 ///
206 /// @param[in] count
207 /// The number of uint16_t values to extract.
208 ///
209 /// @return
210 /// \a dst if all values were properly extracted and copied,
211 /// NULL otherise.
212 uint16_t *getU16(uint32_t *offset_ptr, uint16_t *dst, uint32_t count) const;
213
214 /// Extract a uint32_t value from \a *offset_ptr.
215 ///
216 /// Extract a single uint32_t from the binary data at the offset
217 /// pointed to by \a offset_ptr, and update the offset on success.
218 ///
219 /// @param[in,out] offset_ptr
220 /// A pointer to an offset within the data that will be advanced
221 /// by the appropriate number of bytes if the value is extracted
222 /// correctly. If the offset is out of bounds or there are not
223 /// enough bytes to extract this value, the offset will be left
224 /// unmodified.
225 ///
226 /// @return
227 /// The extracted uint32_t value.
228 uint32_t getU32(uint32_t *offset_ptr) const;
229
230 /// Extract \a count uint32_t values from \a *offset_ptr.
231 ///
232 /// Extract \a count uint32_t values from the binary data at the
233 /// offset pointed to by \a offset_ptr, and advance the offset on
234 /// success. The extracted values are copied into \a dst.
235 ///
236 /// @param[in,out] offset_ptr
237 /// A pointer to an offset within the data that will be advanced
238 /// by the appropriate number of bytes if the value is extracted
239 /// correctly. If the offset is out of bounds or there are not
240 /// enough bytes to extract this value, the offset will be left
241 /// unmodified.
242 ///
243 /// @param[out] dst
244 /// A buffer to copy \a count uint32_t values into. \a dst must
245 /// be large enough to hold all requested data.
246 ///
247 /// @param[in] count
248 /// The number of uint32_t values to extract.
249 ///
250 /// @return
251 /// \a dst if all values were properly extracted and copied,
252 /// NULL otherise.
253 uint32_t *getU32(uint32_t *offset_ptr, uint32_t *dst, uint32_t count) const;
254
255 /// Extract a uint64_t value from \a *offset_ptr.
256 ///
257 /// Extract a single uint64_t from the binary data at the offset
258 /// pointed to by \a offset_ptr, and update the offset on success.
259 ///
260 /// @param[in,out] offset_ptr
261 /// A pointer to an offset within the data that will be advanced
262 /// by the appropriate number of bytes if the value is extracted
263 /// correctly. If the offset is out of bounds or there are not
264 /// enough bytes to extract this value, the offset will be left
265 /// unmodified.
266 ///
267 /// @return
268 /// The extracted uint64_t value.
269 uint64_t getU64(uint32_t *offset_ptr) const;
270
271 /// Extract \a count uint64_t values from \a *offset_ptr.
272 ///
273 /// Extract \a count uint64_t values from the binary data at the
274 /// offset pointed to by \a offset_ptr, and advance the offset on
275 /// success. The extracted values are copied into \a dst.
276 ///
277 /// @param[in,out] offset_ptr
278 /// A pointer to an offset within the data that will be advanced
279 /// by the appropriate number of bytes if the value is extracted
280 /// correctly. If the offset is out of bounds or there are not
281 /// enough bytes to extract this value, the offset will be left
282 /// unmodified.
283 ///
284 /// @param[out] dst
285 /// A buffer to copy \a count uint64_t values into. \a dst must
286 /// be large enough to hold all requested data.
287 ///
288 /// @param[in] count
289 /// The number of uint64_t values to extract.
290 ///
291 /// @return
292 /// \a dst if all values were properly extracted and copied,
293 /// NULL otherise.
294 uint64_t *getU64(uint32_t *offset_ptr, uint64_t *dst, uint32_t count) const;
295
296 /// Extract a signed LEB128 value from \a *offset_ptr.
297 ///
298 /// Extracts an signed LEB128 number from this object's data
299 /// starting at the offset pointed to by \a offset_ptr. The offset
300 /// pointed to by \a offset_ptr will be updated with the offset of
301 /// the byte following the last extracted byte.
302 ///
303 /// @param[in,out] offset_ptr
304 /// A pointer to an offset within the data that will be advanced
305 /// by the appropriate number of bytes if the value is extracted
306 /// correctly. If the offset is out of bounds or there are not
307 /// enough bytes to extract this value, the offset will be left
308 /// unmodified.
309 ///
310 /// @return
311 /// The extracted signed integer value.
312 int64_t getSLEB128(uint32_t *offset_ptr) const;
313
314 /// Extract a unsigned LEB128 value from \a *offset_ptr.
315 ///
316 /// Extracts an unsigned LEB128 number from this object's data
317 /// starting at the offset pointed to by \a offset_ptr. The offset
318 /// pointed to by \a offset_ptr will be updated with the offset of
319 /// the byte following the last extracted byte.
320 ///
321 /// @param[in,out] offset_ptr
322 /// A pointer to an offset within the data that will be advanced
323 /// by the appropriate number of bytes if the value is extracted
324 /// correctly. If the offset is out of bounds or there are not
325 /// enough bytes to extract this value, the offset will be left
326 /// unmodified.
327 ///
328 /// @return
329 /// The extracted unsigned integer value.
330 uint64_t getULEB128(uint32_t *offset_ptr) const;
331
332 /// Test the validity of \a offset.
333 ///
334 /// @return
335 /// \b true if \a offset is a valid offset into the data in this
336 /// object, \b false otherwise.
337 bool isValidOffset(uint32_t offset) const { return Data.size() > offset; }
338
339 /// Test the availability of \a length bytes of data from \a offset.
340 ///
341 /// @return
342 /// \b true if \a offset is a valid offset and there are \a
343 /// length bytes available at that offset, \b false otherwise.
344 bool isValidOffsetForDataOfSize(uint32_t offset, uint32_t length) const {
345 return offset + length >= offset && isValidOffset(offset + length - 1);
346 }
347 };
348
349 } // namespace llvm
350
351 #endif
1414 CommandLine.cpp
1515 ConstantRange.cpp
1616 CrashRecoveryContext.cpp
17 DataExtractor.cpp
1718 Debug.cpp
1819 DeltaAlgorithm.cpp
1920 DAGDeltaAlgorithm.cpp
0 //===-- DataExtractor.cpp -------------------------------------------------===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8
9 #include "llvm/Support/DataExtractor.h"
10 #include "llvm/Support/ErrorHandling.h"
11 #include "llvm/Support/Host.h"
12 #include "llvm/Support/SwapByteOrder.h"
13 using namespace llvm;
14
15 template
16 static T getU(uint32_t *offset_ptr, const DataExtractor *de,
17 bool isLittleEndian, const char *Data) {
18 T val = 0;
19 uint32_t offset = *offset_ptr;
20 if (de->isValidOffsetForDataOfSize(offset, sizeof(val))) {
21 std::memcpy(&val, &Data[offset], sizeof(val));
22 if (sys::isLittleEndianHost() != isLittleEndian)
23 val = sys::SwapByteOrder(val);
24
25 // Advance the offset
26 *offset_ptr += sizeof(val);
27 }
28 return val;
29 }
30
31 template
32 static T *getUs(uint32_t *offset_ptr, T *dst, uint32_t count,
33 const DataExtractor *de, bool isLittleEndian, const char *Data){
34 uint32_t offset = *offset_ptr;
35
36 if (count > 0 && de->isValidOffsetForDataOfSize(offset, sizeof(*dst)*count)) {
37 for (T *value_ptr = dst, *end = dst + count; value_ptr != end;
38 ++value_ptr, offset += sizeof(*dst))
39 *value_ptr = getU(offset_ptr, de, isLittleEndian, Data);
40 // Advance the offset
41 *offset_ptr = offset;
42 // Return a non-NULL pointer to the converted data as an indicator of
43 // success
44 return dst;
45 }
46 return NULL;
47 }
48
49 uint8_t DataExtractor::getU8(uint32_t *offset_ptr) const {
50 return getU(offset_ptr, this, IsLittleEndian, Data.data());
51 }
52
53 uint8_t *
54 DataExtractor::getU8(uint32_t *offset_ptr, uint8_t *dst, uint32_t count) const {
55 return getUs(offset_ptr, dst, count, this, IsLittleEndian,
56 Data.data());
57 }
58
59
60 uint16_t DataExtractor::getU16(uint32_t *offset_ptr) const {
61 return getU(offset_ptr, this, IsLittleEndian, Data.data());
62 }
63
64 uint16_t *DataExtractor::getU16(uint32_t *offset_ptr, uint16_t *dst,
65 uint32_t count) const {
66 return getUs(offset_ptr, dst, count, this, IsLittleEndian,
67 Data.data());
68 }
69
70 uint32_t DataExtractor::getU32(uint32_t *offset_ptr) const {
71 return getU(offset_ptr, this, IsLittleEndian, Data.data());
72 }
73
74 uint32_t *DataExtractor::getU32(uint32_t *offset_ptr, uint32_t *dst,
75 uint32_t count) const {
76 return getUs(offset_ptr, dst, count, this, IsLittleEndian,
77 Data.data());;
78 }
79
80 uint64_t DataExtractor::getU64(uint32_t *offset_ptr) const {
81 return getU(offset_ptr, this, IsLittleEndian, Data.data());
82 }
83
84 uint64_t *DataExtractor::getU64(uint32_t *offset_ptr, uint64_t *dst,
85 uint32_t count) const {
86 return getUs(offset_ptr, dst, count, this, IsLittleEndian,
87 Data.data());
88 }
89
90 uint64_t
91 DataExtractor::getUnsigned(uint32_t *offset_ptr, uint32_t byte_size) const {
92 switch (byte_size) {
93 case 1:
94 return getU8(offset_ptr);
95 case 2:
96 return getU16(offset_ptr);
97 case 4:
98 return getU32(offset_ptr);
99 case 8:
100 return getU64(offset_ptr);
101 }
102 llvm_unreachable("getUnsigned unhandled case!");
103 }
104
105 int64_t
106 DataExtractor::getSigned(uint32_t *offset_ptr, uint32_t byte_size) const {
107 switch (byte_size) {
108 case 1:
109 return (int8_t)getU8(offset_ptr);
110 case 2:
111 return (int16_t)getU16(offset_ptr);
112 case 4:
113 return (int32_t)getU32(offset_ptr);
114 case 8:
115 return (int64_t)getU64(offset_ptr);
116 }
117 llvm_unreachable("getSigned unhandled case!");
118 }
119
120 const char *DataExtractor::getCStr(uint32_t *offset_ptr) const {
121 uint32_t offset = *offset_ptr;
122 StringRef::size_type pos = Data.find('\0', offset);
123 if (pos != StringRef::npos) {
124 *offset_ptr = pos + 1;
125 return Data.data() + offset;
126 }
127 return NULL;
128 }
129
130 uint64_t DataExtractor::getULEB128(uint32_t *offset_ptr) const {
131 uint64_t result = 0;
132 if (Data.empty())
133 return 0;
134
135 unsigned shift = 0;
136 uint32_t offset = *offset_ptr;
137 uint8_t byte = 0;
138
139 while (isValidOffset(offset)) {
140 byte = Data[offset++];
141 result |= (byte & 0x7f) << shift;
142 shift += 7;
143 if ((byte & 0x80) == 0)
144 break;
145 }
146
147 *offset_ptr = offset;
148 return result;
149 }
150
151 int64_t DataExtractor::getSLEB128(uint32_t *offset_ptr) const {
152 int64_t result = 0;
153 if (Data.empty())
154 return 0;
155
156 unsigned shift = 0;
157 uint32_t offset = *offset_ptr;
158 uint8_t byte = 0;
159
160 while (isValidOffset(offset)) {
161 byte = Data[offset++];
162 result |= (byte & 0x7f) << shift;
163 shift += 7;
164 if ((byte & 0x80) == 0)
165 break;
166 }
167
168 // Sign bit of byte is 2nd high order bit (0x40)
169 if (shift < 64 && (byte & 0x40))
170 result |= -(1 << shift);
171
172 *offset_ptr = offset;
173 return result;
174 }
0 //===- llvm/unittest/Support/DataExtractorTest.cpp - DataExtractor tests --===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8
9 #include "gtest/gtest.h"
10 #include "llvm/Support/DataExtractor.h"
11 using namespace llvm;
12
13 namespace {
14
15 const char numberData[] = "\x80\x90\xFF\xFF\x80\x00\x00\x00";
16 const char stringData[] = "hellohello\0hello";
17 const char leb128data[] = "\xA6\x49";
18
19 TEST(DataExtractorTest, OffsetOverflow) {
20 DataExtractor DE(StringRef(numberData, sizeof(numberData)-1), false, 8);
21 EXPECT_FALSE(DE.isValidOffsetForDataOfSize(-2U, 5));
22 }
23
24 TEST(DataExtractorTest, UnsignedNumbers) {
25 DataExtractor DE(StringRef(numberData, sizeof(numberData)-1), false, 8);
26 uint32_t offset = 0;
27
28 EXPECT_EQ(0x80U, DE.getU8(&offset));
29 EXPECT_EQ(1U, offset);
30 offset = 0;
31 EXPECT_EQ(0x8090U, DE.getU16(&offset));
32 EXPECT_EQ(2U, offset);
33 offset = 0;
34 EXPECT_EQ(0x8090FFFFU, DE.getU32(&offset));
35 EXPECT_EQ(4U, offset);
36 offset = 0;
37 EXPECT_EQ(0x8090FFFF80000000U, DE.getU64(&offset));
38 EXPECT_EQ(8U, offset);
39 offset = 0;
40 EXPECT_EQ(0x8090FFFF80000000U, DE.getAddress(&offset));
41 EXPECT_EQ(8U, offset);
42 offset = 0;
43
44 uint32_t data[2];
45 EXPECT_EQ(data, DE.getU32(&offset, data, 2));
46 EXPECT_EQ(0x8090FFFFU, data[0]);
47 EXPECT_EQ(0x80000000U, data[1]);
48 EXPECT_EQ(8U, offset);
49 offset = 0;
50
51 // Now for little endian.
52 DE = DataExtractor(StringRef(numberData, sizeof(numberData)-1), true, 4);
53 EXPECT_EQ(0x9080U, DE.getU16(&offset));
54 EXPECT_EQ(2U, offset);
55 offset = 0;
56 EXPECT_EQ(0xFFFF9080U, DE.getU32(&offset));
57 EXPECT_EQ(4U, offset);
58 offset = 0;
59 EXPECT_EQ(0x80FFFF9080U, DE.getU64(&offset));
60 EXPECT_EQ(8U, offset);
61 offset = 0;
62 EXPECT_EQ(0xFFFF9080U, DE.getAddress(&offset));
63 EXPECT_EQ(4U, offset);
64 offset = 0;
65
66 EXPECT_EQ(data, DE.getU32(&offset, data, 2));
67 EXPECT_EQ(0xFFFF9080U, data[0]);
68 EXPECT_EQ(0x80U, data[1]);
69 EXPECT_EQ(8U, offset);
70 }
71
72 TEST(DataExtractorTest, SignedNumbers) {
73 DataExtractor DE(StringRef(numberData, sizeof(numberData)-1), false, 8);
74 uint32_t offset = 0;
75
76 EXPECT_EQ(-128, DE.getSigned(&offset, 1));
77 EXPECT_EQ(1U, offset);
78 offset = 0;
79 EXPECT_EQ(-32624, DE.getSigned(&offset, 2));
80 EXPECT_EQ(2U, offset);
81 offset = 0;
82 EXPECT_EQ(-2137980929, DE.getSigned(&offset, 4));
83 EXPECT_EQ(4U, offset);
84 offset = 0;
85 EXPECT_EQ(-9182558167379214336LL, DE.getSigned(&offset, 8));
86 EXPECT_EQ(8U, offset);
87 }
88
89 TEST(DataExtractorTest, Strings) {
90 DataExtractor DE(StringRef(stringData, sizeof(stringData)-1), false, 8);
91 uint32_t offset = 0;
92
93 EXPECT_EQ(stringData, DE.getCStr(&offset));
94 EXPECT_EQ(11U, offset);
95 EXPECT_EQ(NULL, DE.getCStr(&offset));
96 EXPECT_EQ(11U, offset);
97 }
98
99 TEST(DataExtractorTest, LEB128) {
100 DataExtractor DE(StringRef(leb128data, sizeof(leb128data)-1), false, 8);
101 uint32_t offset = 0;
102
103 EXPECT_EQ(9382ULL, DE.getULEB128(&offset));
104 EXPECT_EQ(2U, offset);
105 offset = 0;
106 EXPECT_EQ(-7002LL, DE.getSLEB128(&offset));
107 EXPECT_EQ(2U, offset);
108 }
109
110 }