LLVM 24.0.0git
DataExtractor.h
Go to the documentation of this file.
1//===-- DataExtractor.h -----------------------------------------*- C++ -*-===//
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#ifndef LLVM_SUPPORT_DATAEXTRACTOR_H
10#define LLVM_SUPPORT_DATAEXTRACTOR_H
11
12#include "llvm/ADT/APSInt.h"
13#include "llvm/ADT/StringRef.h"
16#include "llvm/Support/Error.h"
17
18namespace llvm {
19
20/// An auxiliary type to facilitate extraction of 3-byte entities.
21struct Uint24 {
23 Uint24(uint8_t U) : Bytes{U, U, U} {}
24 Uint24(uint8_t U0, uint8_t U1, uint8_t U2) : Bytes{U0, U1, U2} {}
25 uint32_t getAsUint32(bool IsLittleEndian) const {
26 int LoIx = IsLittleEndian ? 0 : 2;
27 return Bytes[LoIx] + (Bytes[1] << 8) + (Bytes[2-LoIx] << 16);
28 }
29};
30
32static_assert(sizeof(uint24_t) == 3, "sizeof(uint24_t) != 3");
33
34/// Needed by swapByteOrder().
36 return uint24_t(C.Bytes[2], C.Bytes[1], C.Bytes[0]);
37}
38
40 StringRef Data;
41 uint8_t IsLittleEndian;
42
43public:
44 /// A class representing a position in a DataExtractor, as well as any error
45 /// encountered during extraction. It enables one to extract a sequence of
46 /// values without error-checking and then checking for errors in bulk at the
47 /// end. The class holds an Error object, so failing to check the result of
48 /// the parse will result in a runtime error. The error flag is sticky and
49 /// will cause all subsequent extraction functions to fail without even
50 /// attempting to parse and without updating the Cursor offset. After clearing
51 /// the error flag, one can again use the Cursor object for parsing.
52 class Cursor {
53 uint64_t Offset;
54 Error Err;
55
56 friend class DataExtractor;
57
58 public:
59 /// Construct a cursor for extraction from the given offset.
60 explicit Cursor(uint64_t Offset) : Offset(Offset), Err(Error::success()) {}
61
62 /// Checks whether the cursor is valid (i.e. no errors were encountered). In
63 /// case of errors, this does not clear the error flag -- one must call
64 /// takeError() instead.
65 explicit operator bool() { return !Err; }
66
67 /// Return the current position of this Cursor. In the error state this is
68 /// the position of the Cursor before the first error was encountered.
69 uint64_t tell() const { return Offset; }
70
71 /// Set the cursor to the new offset. This does not impact the error state.
72 void seek(uint64_t NewOffSet) { Offset = NewOffSet; }
73
74 /// Return error contained inside this Cursor, if any. Clears the internal
75 /// Cursor state.
76 Error takeError() { return std::move(Err); }
77 };
78
79 /// Construct with a buffer that is owned by the caller.
80 ///
81 /// This constructor allows us to use data that is owned by the
82 /// caller. The data must stay around as long as this object is
83 /// valid.
84 DataExtractor(StringRef Data, bool IsLittleEndian)
85 : Data(Data), IsLittleEndian(IsLittleEndian) {}
86
87 DataExtractor(ArrayRef<uint8_t> Data, bool IsLittleEndian)
88 : Data(StringRef(reinterpret_cast<const char *>(Data.data()),
89 Data.size())),
90 IsLittleEndian(IsLittleEndian) {}
91
92 /// Get the data pointed to by this extractor.
93 StringRef getData() const { return Data; }
94 /// Get the endianness for this extractor.
95 bool isLittleEndian() const { return IsLittleEndian; }
96
97 /// Extract a C string from \a *offset_ptr.
98 ///
99 /// Returns a pointer to a C String from the data at the offset
100 /// pointed to by \a offset_ptr. A variable length NULL terminated C
101 /// string will be extracted and the \a offset_ptr will be
102 /// updated with the offset of the byte that follows the NULL
103 /// terminator byte.
104 ///
105 /// @param[in,out] OffsetPtr
106 /// A pointer to an offset within the data that will be advanced
107 /// by the appropriate number of bytes if the value is extracted
108 /// correctly. If the offset is out of bounds or there are not
109 /// enough bytes to extract this value, the offset will be left
110 /// unmodified.
111 ///
112 /// @param[in,out] Err
113 /// A pointer to an Error object. Upon return the Error object is set to
114 /// indicate the result (success/failure) of the function. If the Error
115 /// object is already set when calling this function, no extraction is
116 /// performed.
117 ///
118 /// @return
119 /// A pointer to the C string value in the data. If the offset
120 /// pointed to by \a offset_ptr is out of bounds, or if the
121 /// offset plus the length of the C string is out of bounds,
122 /// NULL will be returned.
123 const char *getCStr(uint64_t *OffsetPtr, Error *Err = nullptr) const {
124 return getCStrRef(OffsetPtr, Err).data();
125 }
126
127 /// Extract a C string from the location given by the cursor. In case of an
128 /// extraction error, or if the cursor is already in an error state, a
129 /// nullptr is returned.
130 const char *getCStr(Cursor &C) const { return getCStrRef(C).data(); }
131
132 /// Extract a C string from \a *offset_ptr.
133 ///
134 /// Returns a StringRef for the C String from the data at the offset
135 /// pointed to by \a offset_ptr. A variable length NULL terminated C
136 /// string will be extracted and the \a offset_ptr will be
137 /// updated with the offset of the byte that follows the NULL
138 /// terminator byte.
139 ///
140 /// \param[in,out] OffsetPtr
141 /// A pointer to an offset within the data that will be advanced
142 /// by the appropriate number of bytes if the value is extracted
143 /// correctly. If the offset is out of bounds or there are not
144 /// enough bytes to extract this value, the offset will be left
145 /// unmodified.
146 ///
147 /// @param[in,out] Err
148 /// A pointer to an Error object. Upon return the Error object is set to
149 /// indicate the result (success/failure) of the function. If the Error
150 /// object is already set when calling this function, no extraction is
151 /// performed.
152 ///
153 /// \return
154 /// A StringRef for the C string value in the data. If the offset
155 /// pointed to by \a offset_ptr is out of bounds, or if the
156 /// offset plus the length of the C string is out of bounds,
157 /// a default-initialized StringRef will be returned.
159 Error *Err = nullptr) const;
160
161 /// Extract a C string (as a StringRef) from the location given by the cursor.
162 /// In case of an extraction error, or if the cursor is already in an error
163 /// state, a default-initialized StringRef is returned.
165 return getCStrRef(&C.Offset, &C.Err);
166 }
167
168 /// Extract a fixed length string from \a *OffsetPtr and consume \a Length
169 /// bytes.
170 ///
171 /// Returns a StringRef for the string from the data at the offset
172 /// pointed to by \a OffsetPtr. A fixed length C string will be extracted
173 /// and the \a OffsetPtr will be advanced by \a Length bytes.
174 ///
175 /// \param[in,out] OffsetPtr
176 /// A pointer to an offset within the data that will be advanced
177 /// by the appropriate number of bytes if the value is extracted
178 /// correctly. If the offset is out of bounds or there are not
179 /// enough bytes to extract this value, the offset will be left
180 /// unmodified.
181 ///
182 /// \param[in] Length
183 /// The length of the fixed length string to extract. If there are not
184 /// enough bytes in the data to extract the full string, the offset will
185 /// be left unmodified.
186 ///
187 /// \param[in] TrimChars
188 /// A set of characters to trim from the end of the string. Fixed length
189 /// strings are commonly either NULL terminated by one or more zero
190 /// bytes. Some clients have one or more spaces at the end of the string,
191 /// but a good default is to trim the NULL characters.
192 ///
193 /// \return
194 /// A StringRef for the C string value in the data. If the offset
195 /// pointed to by \a OffsetPtr is out of bounds, or if the
196 /// offset plus the length of the C string is out of bounds,
197 /// a default-initialized StringRef will be returned.
199 StringRef TrimChars = {"\0",
200 1}) const;
201
202 /// Extract a fixed number of bytes from the specified offset.
203 ///
204 /// Returns a StringRef for the bytes from the data at the offset
205 /// pointed to by \a OffsetPtr. A fixed length C string will be extracted
206 /// and the \a OffsetPtr will be advanced by \a Length bytes.
207 ///
208 /// \param[in,out] OffsetPtr
209 /// A pointer to an offset within the data that will be advanced
210 /// by the appropriate number of bytes if the value is extracted
211 /// correctly. If the offset is out of bounds or there are not
212 /// enough bytes to extract this value, the offset will be left
213 /// unmodified.
214 ///
215 /// \param[in] Length
216 /// The number of bytes to extract. If there are not enough bytes in the
217 /// data to extract all of the bytes, the offset will be left unmodified.
218 ///
219 /// @param[in,out] Err
220 /// A pointer to an Error object. Upon return the Error object is set to
221 /// indicate the result (success/failure) of the function. If the Error
222 /// object is already set when calling this function, no extraction is
223 /// performed.
224 ///
225 /// \return
226 /// A StringRef for the extracted bytes. If the offset pointed to by
227 /// \a OffsetPtr is out of bounds, or if the offset plus the length
228 /// is out of bounds, a default-initialized StringRef will be returned.
229 LLVM_ABI StringRef getBytes(uint64_t *OffsetPtr, uint64_t Length,
230 Error *Err = nullptr) const;
231
232 /// Extract a fixed number of bytes from the location given by the cursor. In
233 /// case of an extraction error, or if the cursor is already in an error
234 /// state, a default-initialized StringRef is returned.
236 return getBytes(&C.Offset, Length, &C.Err);
237 }
238
239 /// Extract an unsigned integer of size \a byte_size from \a
240 /// *offset_ptr.
241 ///
242 /// Extract a single unsigned integer value and update the offset
243 /// pointed to by \a offset_ptr. The size of the extracted integer
244 /// is specified by the \a byte_size argument. \a byte_size should
245 /// have a value greater than or equal to one and less than or equal
246 /// to eight since the return value is 64 bits wide. Any
247 /// \a byte_size values less than 1 or greater than 8 will result in
248 /// nothing being extracted, and zero being returned.
249 ///
250 /// @param[in,out] offset_ptr
251 /// A pointer to an offset within the data that will be advanced
252 /// by the appropriate number of bytes if the value is extracted
253 /// correctly. If the offset is out of bounds or there are not
254 /// enough bytes to extract this value, the offset will be left
255 /// unmodified.
256 ///
257 /// @param[in] byte_size
258 /// The size in byte of the integer to extract.
259 ///
260 /// @param[in,out] Err
261 /// A pointer to an Error object. Upon return the Error object is set to
262 /// indicate the result (success/failure) of the function. If the Error
263 /// object is already set when calling this function, no extraction is
264 /// performed.
265 ///
266 /// @return
267 /// The unsigned integer value that was extracted, or zero on
268 /// failure.
269 LLVM_ABI uint64_t getUnsigned(uint64_t *offset_ptr, uint32_t byte_size,
270 Error *Err = nullptr) const;
271
272 /// Extract an unsigned integer of the given size from the location given by
273 /// the cursor. In case of an extraction error, or if the cursor is already in
274 /// an error state, zero is returned.
276 return getUnsigned(&C.Offset, Size, &C.Err);
277 }
278
279 /// Extract an signed integer of size \a byte_size from \a *offset_ptr.
280 ///
281 /// Extract a single signed integer value (sign extending if required)
282 /// and update the offset pointed to by \a offset_ptr. The size of
283 /// the extracted integer is specified by the \a byte_size argument.
284 /// \a byte_size should have a value greater than or equal to one
285 /// and less than or equal to eight since the return value is 64
286 /// bits wide. Any \a byte_size values less than 1 or greater than
287 /// 8 will result in nothing being extracted, and zero being returned.
288 ///
289 /// @param[in,out] offset_ptr
290 /// A pointer to an offset within the data that will be advanced
291 /// by the appropriate number of bytes if the value is extracted
292 /// correctly. If the offset is out of bounds or there are not
293 /// enough bytes to extract this value, the offset will be left
294 /// unmodified.
295 ///
296 /// @param[in] size
297 /// The size in bytes of the integer to extract.
298 ///
299 /// @return
300 /// The sign extended signed integer value that was extracted,
301 /// or zero on failure.
302 LLVM_ABI int64_t getSigned(uint64_t *offset_ptr, uint32_t size) const;
303
304 /// Extract a uint8_t value from \a *offset_ptr.
305 ///
306 /// Extract a single uint8_t from the binary data at the offset
307 /// pointed to by \a offset_ptr, and advance the offset on success.
308 ///
309 /// @param[in,out] offset_ptr
310 /// A pointer to an offset within the data that will be advanced
311 /// by the appropriate number of bytes if the value is extracted
312 /// correctly. If the offset is out of bounds or there are not
313 /// enough bytes to extract this value, the offset will be left
314 /// unmodified.
315 ///
316 /// @param[in,out] Err
317 /// A pointer to an Error object. Upon return the Error object is set to
318 /// indicate the result (success/failure) of the function. If the Error
319 /// object is already set when calling this function, no extraction is
320 /// performed.
321 ///
322 /// @return
323 /// The extracted uint8_t value.
324 LLVM_ABI uint8_t getU8(uint64_t *offset_ptr, Error *Err = nullptr) const;
325
326 /// Extract a single uint8_t value from the location given by the cursor. In
327 /// case of an extraction error, or if the cursor is already in an error
328 /// state, zero is returned.
329 uint8_t getU8(Cursor &C) const { return getU8(&C.Offset, &C.Err); }
330
331 /// Extract \a count uint8_t values from \a *offset_ptr.
332 ///
333 /// Extract \a count uint8_t values from the binary data at the
334 /// offset pointed to by \a offset_ptr, and advance the offset on
335 /// success. The extracted values are copied into \a dst.
336 ///
337 /// @param[in,out] offset_ptr
338 /// A pointer to an offset within the data that will be advanced
339 /// by the appropriate number of bytes if the value is extracted
340 /// correctly. If the offset is out of bounds or there are not
341 /// enough bytes to extract this value, the offset will be left
342 /// unmodified.
343 ///
344 /// @param[out] dst
345 /// A buffer to copy \a count uint8_t values into. \a dst must
346 /// be large enough to hold all requested data.
347 ///
348 /// @param[in] count
349 /// The number of uint8_t values to extract.
350 ///
351 /// @return
352 /// \a dst if all values were properly extracted and copied,
353 /// NULL otherise.
354 LLVM_ABI uint8_t *getU8(uint64_t *offset_ptr, uint8_t *dst,
355 uint32_t count) const;
356
357 /// Extract \a Count uint8_t values from the location given by the cursor and
358 /// store them into the destination buffer. In case of an extraction error, or
359 /// if the cursor is already in an error state, a nullptr is returned and the
360 /// destination buffer is left unchanged.
361 LLVM_ABI uint8_t *getU8(Cursor &C, uint8_t *Dst, uint32_t Count) const;
362
363 /// Extract \a Count uint8_t values from the location given by the cursor and
364 /// store them into the destination vector. The vector is resized to fit the
365 /// extracted data. In case of an extraction error, or if the cursor is
366 /// already in an error state, the destination vector is left unchanged and
367 /// cursor is placed into an error state.
370 Dst.resize(Count);
371
372 // This relies on the fact that getU8 will not attempt to write to the
373 // buffer if isValidOffsetForDataOfSize(C.Offset, Count) is false.
374 getU8(C, Dst.data(), Count);
375 }
376
377 /// Extract a int8_t value from \a *OffsetPtr. In case of an extraction error,
378 /// or if error is already set, zero is returned and the offset is left
379 /// unmodified.
380 int8_t getS8(uint64_t *OffsetPtr, Error *Err = nullptr) const {
381 return static_cast<int8_t>(getU8(OffsetPtr, Err));
382 }
383
384 /// Extract a int8_t value from \a *OffsetPtr. In case of an extraction error,
385 /// or if the cursor is already in an error state, zero is returned and the
386 /// offset is left unmodified.
387 int8_t getS8(Cursor &C) const { return static_cast<int8_t>(getU8(C)); }
388
389 //------------------------------------------------------------------
390 /// Extract a uint16_t value from \a *offset_ptr.
391 ///
392 /// Extract a single uint16_t from the binary data at the offset
393 /// pointed to by \a offset_ptr, and update the offset on success.
394 ///
395 /// @param[in,out] offset_ptr
396 /// A pointer to an offset within the data that will be advanced
397 /// by the appropriate number of bytes if the value is extracted
398 /// correctly. If the offset is out of bounds or there are not
399 /// enough bytes to extract this value, the offset will be left
400 /// unmodified.
401 ///
402 /// @param[in,out] Err
403 /// A pointer to an Error object. Upon return the Error object is set to
404 /// indicate the result (success/failure) of the function. If the Error
405 /// object is already set when calling this function, no extraction is
406 /// performed.
407 ///
408 /// @return
409 /// The extracted uint16_t value.
410 //------------------------------------------------------------------
411 LLVM_ABI uint16_t getU16(uint64_t *offset_ptr, Error *Err = nullptr) const;
412
413 /// Extract a single uint16_t value from the location given by the cursor. In
414 /// case of an extraction error, or if the cursor is already in an error
415 /// state, zero is returned.
416 uint16_t getU16(Cursor &C) const { return getU16(&C.Offset, &C.Err); }
417
418 /// Extract \a count uint16_t values from \a *offset_ptr.
419 ///
420 /// Extract \a count uint16_t values from the binary data at the
421 /// offset pointed to by \a offset_ptr, and advance the offset on
422 /// success. The extracted values are copied into \a dst.
423 ///
424 /// @param[in,out] offset_ptr
425 /// A pointer to an offset within the data that will be advanced
426 /// by the appropriate number of bytes if the value is extracted
427 /// correctly. If the offset is out of bounds or there are not
428 /// enough bytes to extract this value, the offset will be left
429 /// unmodified.
430 ///
431 /// @param[out] dst
432 /// A buffer to copy \a count uint16_t values into. \a dst must
433 /// be large enough to hold all requested data.
434 ///
435 /// @param[in] count
436 /// The number of uint16_t values to extract.
437 ///
438 /// @return
439 /// \a dst if all values were properly extracted and copied,
440 /// NULL otherise.
441 LLVM_ABI uint16_t *getU16(uint64_t *offset_ptr, uint16_t *dst,
442 uint32_t count) const;
443
444 /// Extract a int16_t value from \a *OffsetPtr. In case of an extraction
445 /// error, or if error is already set, zero is returned and the offset is left
446 /// unmodified.
447 int16_t getS16(uint64_t *OffsetPtr, Error *Err = nullptr) const {
448 return static_cast<int16_t>(getU16(OffsetPtr, Err));
449 }
450
451 /// Extract a int16_t value from \a *OffsetPtr. In case of an extraction
452 /// error, or if the cursor is already in an error state, zero is returned and
453 /// the offset is left unmodified.
454 int16_t getS16(Cursor &C) const { return static_cast<int16_t>(getU16(C)); }
455
456 /// Extract a 24-bit unsigned value from \a *offset_ptr and return it
457 /// in a uint32_t.
458 ///
459 /// Extract 3 bytes from the binary data at the offset pointed to by
460 /// \a offset_ptr, construct a uint32_t from them and update the offset
461 /// on success.
462 ///
463 /// @param[in,out] OffsetPtr
464 /// A pointer to an offset within the data that will be advanced
465 /// by the 3 bytes if the value is extracted correctly. If the offset
466 /// is out of bounds or there are not enough bytes to extract this value,
467 /// the offset will be left unmodified.
468 ///
469 /// @param[in,out] Err
470 /// A pointer to an Error object. Upon return the Error object is set to
471 /// indicate the result (success/failure) of the function. If the Error
472 /// object is already set when calling this function, no extraction is
473 /// performed.
474 ///
475 /// @return
476 /// The extracted 24-bit value represented in a uint32_t.
477 LLVM_ABI uint32_t getU24(uint64_t *OffsetPtr, Error *Err = nullptr) const;
478
479 /// Extract a single 24-bit unsigned value from the location given by the
480 /// cursor. In case of an extraction error, or if the cursor is already in an
481 /// error state, zero is returned.
482 uint32_t getU24(Cursor &C) const { return getU24(&C.Offset, &C.Err); }
483
484 /// Extract a uint32_t value from \a *offset_ptr.
485 ///
486 /// Extract a single uint32_t from the binary data at the offset
487 /// pointed to by \a offset_ptr, and update the offset on success.
488 ///
489 /// @param[in,out] offset_ptr
490 /// A pointer to an offset within the data that will be advanced
491 /// by the appropriate number of bytes if the value is extracted
492 /// correctly. If the offset is out of bounds or there are not
493 /// enough bytes to extract this value, the offset will be left
494 /// unmodified.
495 ///
496 /// @param[in,out] Err
497 /// A pointer to an Error object. Upon return the Error object is set to
498 /// indicate the result (success/failure) of the function. If the Error
499 /// object is already set when calling this function, no extraction is
500 /// performed.
501 ///
502 /// @return
503 /// The extracted uint32_t value.
504 LLVM_ABI uint32_t getU32(uint64_t *offset_ptr, Error *Err = nullptr) const;
505
506 /// Extract a single uint32_t value from the location given by the cursor. In
507 /// case of an extraction error, or if the cursor is already in an error
508 /// state, zero is returned.
509 uint32_t getU32(Cursor &C) const { return getU32(&C.Offset, &C.Err); }
510
511 /// Extract \a count uint32_t values from \a *offset_ptr.
512 ///
513 /// Extract \a count uint32_t values from the binary data at the
514 /// offset pointed to by \a offset_ptr, and advance the offset on
515 /// success. The extracted values are copied into \a dst.
516 ///
517 /// @param[in,out] offset_ptr
518 /// A pointer to an offset within the data that will be advanced
519 /// by the appropriate number of bytes if the value is extracted
520 /// correctly. If the offset is out of bounds or there are not
521 /// enough bytes to extract this value, the offset will be left
522 /// unmodified.
523 ///
524 /// @param[out] dst
525 /// A buffer to copy \a count uint32_t values into. \a dst must
526 /// be large enough to hold all requested data.
527 ///
528 /// @param[in] count
529 /// The number of uint32_t values to extract.
530 ///
531 /// @return
532 /// \a dst if all values were properly extracted and copied,
533 /// NULL otherise.
534 LLVM_ABI uint32_t *getU32(uint64_t *offset_ptr, uint32_t *dst,
535 uint32_t count) const;
536
537 /// Extract a int32_t value from \a *OffsetPtr. In case of an extraction
538 /// error, or if error is already set, zero is returned and the offset is left
539 /// unmodified.
540 int32_t getS32(uint64_t *OffsetPtr, Error *Err = nullptr) const {
541 return static_cast<int32_t>(getU32(OffsetPtr, Err));
542 }
543
544 /// Extract a int32_t value from \a *OffsetPtr. In case of an extraction
545 /// error, or if the cursor is already in an error state, zero is returned and
546 /// the offset is left unmodified.
547 int32_t getS32(Cursor &C) const { return static_cast<int32_t>(getU32(C)); }
548
549 /// Extract a uint64_t value from \a *offset_ptr.
550 ///
551 /// Extract a single uint64_t from the binary data at the offset
552 /// pointed to by \a offset_ptr, and update the offset on success.
553 ///
554 /// @param[in,out] offset_ptr
555 /// A pointer to an offset within the data that will be advanced
556 /// by the appropriate number of bytes if the value is extracted
557 /// correctly. If the offset is out of bounds or there are not
558 /// enough bytes to extract this value, the offset will be left
559 /// unmodified.
560 ///
561 /// @param[in,out] Err
562 /// A pointer to an Error object. Upon return the Error object is set to
563 /// indicate the result (success/failure) of the function. If the Error
564 /// object is already set when calling this function, no extraction is
565 /// performed.
566 ///
567 /// @return
568 /// The extracted uint64_t value.
569 LLVM_ABI uint64_t getU64(uint64_t *offset_ptr, Error *Err = nullptr) const;
570
571 /// Extract a single uint64_t value from the location given by the cursor. In
572 /// case of an extraction error, or if the cursor is already in an error
573 /// state, zero is returned.
574 uint64_t getU64(Cursor &C) const { return getU64(&C.Offset, &C.Err); }
575
576 /// Extract \a count uint64_t values from \a *offset_ptr.
577 ///
578 /// Extract \a count uint64_t values from the binary data at the
579 /// offset pointed to by \a offset_ptr, and advance the offset on
580 /// success. The extracted values are copied into \a dst.
581 ///
582 /// @param[in,out] offset_ptr
583 /// A pointer to an offset within the data that will be advanced
584 /// by the appropriate number of bytes if the value is extracted
585 /// correctly. If the offset is out of bounds or there are not
586 /// enough bytes to extract this value, the offset will be left
587 /// unmodified.
588 ///
589 /// @param[out] dst
590 /// A buffer to copy \a count uint64_t values into. \a dst must
591 /// be large enough to hold all requested data.
592 ///
593 /// @param[in] count
594 /// The number of uint64_t values to extract.
595 ///
596 /// @return
597 /// \a dst if all values were properly extracted and copied,
598 /// NULL otherise.
599 LLVM_ABI uint64_t *getU64(uint64_t *offset_ptr, uint64_t *dst,
600 uint32_t count) const;
601
602 /// Extract a int64_t value from \a *OffsetPtr. In case of an extraction
603 /// error, or if error is already set, zero is returned and the offset is left
604 /// unmodified.
605 int64_t getS64(uint64_t *OffsetPtr, Error *Err = nullptr) const {
606 return static_cast<int64_t>(getU64(OffsetPtr, Err));
607 }
608
609 /// Extract a int64_t value from \a *OffsetPtr. In case of an extraction
610 /// error, or if the cursor is already in an error state, zero is returned and
611 /// the offset is left unmodified.
612 int64_t getS64(Cursor &C) const { return static_cast<int64_t>(getU64(C)); }
613
614 /// Extract a signed LEB128 value from \a *offset_ptr.
615 ///
616 /// Extracts an signed LEB128 number from this object's data
617 /// starting at the offset pointed to by \a offset_ptr. The offset
618 /// pointed to by \a offset_ptr will be updated with the offset of
619 /// the byte following the last extracted byte.
620 ///
621 /// @param[in,out] OffsetPtr
622 /// A pointer to an offset within the data that will be advanced
623 /// by the appropriate number of bytes if the value is extracted
624 /// correctly. If the offset is out of bounds or there are not
625 /// enough bytes to extract this value, the offset will be left
626 /// unmodified.
627 ///
628 /// @param[in,out] Err
629 /// A pointer to an Error object. Upon return the Error object is set to
630 /// indicate the result (success/failure) of the function. If the Error
631 /// object is already set when calling this function, no extraction is
632 /// performed.
633 ///
634 /// @return
635 /// The extracted signed integer value.
636 LLVM_ABI int64_t getSLEB128(uint64_t *OffsetPtr, Error *Err = nullptr) const;
637
638 /// Extract an signed LEB128 value from the location given by the cursor.
639 /// In case of an extraction error, or if the cursor is already in an error
640 /// state, zero is returned.
641 int64_t getSLEB128(Cursor &C) const { return getSLEB128(&C.Offset, &C.Err); }
642
643 /// Extract a unsigned LEB128 value from \a *offset_ptr.
644 ///
645 /// Extracts an unsigned LEB128 number from this object's data
646 /// starting at the offset pointed to by \a offset_ptr. The offset
647 /// pointed to by \a offset_ptr will be updated with the offset of
648 /// the byte following the last extracted byte.
649 ///
650 /// @param[in,out] offset_ptr
651 /// A pointer to an offset within the data that will be advanced
652 /// by the appropriate number of bytes if the value is extracted
653 /// correctly. If the offset is out of bounds or there are not
654 /// enough bytes to extract this value, the offset will be left
655 /// unmodified.
656 ///
657 /// @param[in,out] Err
658 /// A pointer to an Error object. Upon return the Error object is set to
659 /// indicate the result (success/failure) of the function. If the Error
660 /// object is already set when calling this function, no extraction is
661 /// performed.
662 ///
663 /// @return
664 /// The extracted unsigned integer value.
666 llvm::Error *Err = nullptr) const;
667
668 /// Extract an unsigned LEB128 value from the location given by the cursor.
669 /// In case of an extraction error, or if the cursor is already in an error
670 /// state, zero is returned.
671 uint64_t getULEB128(Cursor &C) const { return getULEB128(&C.Offset, &C.Err); }
672
673 /// Extract an arbitrary-precision signed LEB128 value from \a *OffsetPtr.
674 ///
675 /// Extracts a signed LEB128 number from this object's data starting at the
676 /// offset pointed to by \a OffsetPtr, growing the result to as many bits as
677 /// the encoding requires. This differs from getSLEB128(), which is limited to
678 /// 64 bits. The offset pointed to by \a OffsetPtr will be updated with the
679 /// offset of the byte following the last extracted byte.
680 ///
681 /// \param[in,out] OffsetPtr
682 /// A pointer to an offset within the data that will be advanced by the
683 /// appropriate number of bytes if the value is extracted correctly. If
684 /// the offset is out of bounds or there are not enough bytes to extract
685 /// this value, the offset will be left unmodified.
686 ///
687 /// \param[in,out] Err
688 /// A pointer to an Error object. Upon return the Error object is set to
689 /// indicate the result (success/failure) of the function. If the Error
690 /// object is already set when calling this function, no extraction is
691 /// performed.
692 ///
693 /// \return
694 /// The extracted signed integer value, represented with just enough bits
695 /// to hold it.
697 Error *Err = nullptr) const;
698
699 /// Extract an arbitrary-precision signed LEB128 value from the location
700 /// given by the cursor. In case of an extraction error, or if the cursor
701 /// is already in an error state, a default-constructed APSInt is returned.
703 return getSLEB128APSInt(&C.Offset, &C.Err);
704 }
705
706 /// Advance the Cursor position by the given number of bytes. No-op if the
707 /// cursor is in an error state.
708 LLVM_ABI void skip(Cursor &C, uint64_t Length) const;
709
710 /// Return true iff the cursor is at the end of the buffer, regardless of the
711 /// error state of the cursor. The only way both eof and error states can be
712 /// true is if one attempts a read while the cursor is at the very end of the
713 /// data buffer.
714 bool eof(const Cursor &C) const { return size() == C.Offset; }
715
716 /// Test the validity of \a offset.
717 ///
718 /// @return
719 /// \b true if \a offset is a valid offset into the data in this
720 /// object, \b false otherwise.
721 bool isValidOffset(uint64_t offset) const { return size() > offset; }
722
723 /// Test the availability of \a length bytes of data from \a offset.
724 ///
725 /// @return
726 /// \b true if \a offset is a valid offset and there are \a
727 /// length bytes available at that offset, \b false otherwise.
728 bool isValidOffsetForDataOfSize(uint64_t offset, uint64_t length) const {
729 return offset + length >= offset && isValidOffset(offset + length - 1);
730 }
731
732 /// Return the number of bytes in the underlying buffer.
733 size_t size() const { return Data.size(); }
734
735protected:
736 // Make it possible for subclasses to access these fields without making them
737 // public.
738 static uint64_t &getOffset(Cursor &C) { return C.Offset; }
739 static Error &getError(Cursor &C) { return C.Err; }
740
741private:
742 /// If it is possible to read \a Size bytes at offset \a Offset, returns \b
743 /// true. Otherwise, returns \b false. If \a E is not nullptr, also sets the
744 /// error object to indicate an error.
745 bool prepareRead(uint64_t Offset, uint64_t Size, Error *E) const;
746
747 template <typename T> T getU(uint64_t *OffsetPtr, Error *Err) const;
748 template <typename T>
749 T *getUs(uint64_t *OffsetPtr, T *Dst, uint32_t Count, Error *Err) const;
750};
751
752} // namespace llvm
753
754#endif
aarch64 promote const
unsigned uint64_t
This file implements the APSInt class, which is a simple class that represents an arbitrary sized int...
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
#define LLVM_ABI
Definition Compiler.h:215
#define T
static Split data
An arbitrary precision integer that knows its signedness.
Definition APSInt.h:24
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
A class representing a position in a DataExtractor, as well as any error encountered during extractio...
Cursor(uint64_t Offset)
Construct a cursor for extraction from the given offset.
uint64_t tell() const
Return the current position of this Cursor.
Error takeError()
Return error contained inside this Cursor, if any.
void seek(uint64_t NewOffSet)
Set the cursor to the new offset. This does not impact the error state.
LLVM_ABI StringRef getFixedLengthString(uint64_t *OffsetPtr, uint64_t Length, StringRef TrimChars={"\0", 1}) const
Extract a fixed length string from *OffsetPtr and consume Length bytes.
uint32_t getU32(Cursor &C) const
Extract a single uint32_t value from the location given by the cursor.
LLVM_ABI uint64_t getUnsigned(uint64_t *offset_ptr, uint32_t byte_size, Error *Err=nullptr) const
Extract an unsigned integer of size byte_size from *offset_ptr.
LLVM_ABI uint32_t getU32(uint64_t *offset_ptr, Error *Err=nullptr) const
Extract a uint32_t value from *offset_ptr.
size_t size() const
Return the number of bytes in the underlying buffer.
const char * getCStr(uint64_t *OffsetPtr, Error *Err=nullptr) const
Extract a C string from *offset_ptr.
void getU8(Cursor &C, SmallVectorImpl< uint8_t > &Dst, uint32_t Count) const
Extract Count uint8_t values from the location given by the cursor and store them into the destinatio...
int16_t getS16(uint64_t *OffsetPtr, Error *Err=nullptr) const
Extract a int16_t value from *OffsetPtr.
int8_t getS8(uint64_t *OffsetPtr, Error *Err=nullptr) const
Extract a int8_t value from *OffsetPtr.
int64_t getSLEB128(Cursor &C) const
Extract an signed LEB128 value from the location given by the cursor.
static uint64_t & getOffset(Cursor &C)
int32_t getS32(uint64_t *OffsetPtr, Error *Err=nullptr) const
Extract a int32_t value from *OffsetPtr.
bool eof(const Cursor &C) const
Return true iff the cursor is at the end of the buffer, regardless of the error state of the cursor.
LLVM_ABI StringRef getCStrRef(uint64_t *OffsetPtr, Error *Err=nullptr) const
Extract a C string from *offset_ptr.
LLVM_ABI uint8_t getU8(uint64_t *offset_ptr, Error *Err=nullptr) const
Extract a uint8_t value from *offset_ptr.
DataExtractor(StringRef Data, bool IsLittleEndian)
Construct with a buffer that is owned by the caller.
LLVM_ABI int64_t getSigned(uint64_t *offset_ptr, uint32_t size) const
Extract an signed integer of size byte_size from *offset_ptr.
int64_t getS64(uint64_t *OffsetPtr, Error *Err=nullptr) const
Extract a int64_t value from *OffsetPtr.
LLVM_ABI uint64_t getULEB128(uint64_t *offset_ptr, llvm::Error *Err=nullptr) const
Extract a unsigned LEB128 value from *offset_ptr.
uint64_t getUnsigned(Cursor &C, uint32_t Size) const
Extract an unsigned integer of the given size from the location given by the cursor.
uint64_t getULEB128(Cursor &C) const
Extract an unsigned LEB128 value from the location given by the cursor.
uint32_t getU24(Cursor &C) const
Extract a single 24-bit unsigned value from the location given by the cursor.
StringRef getData() const
Get the data pointed to by this extractor.
LLVM_ABI int64_t getSLEB128(uint64_t *OffsetPtr, Error *Err=nullptr) const
Extract a signed LEB128 value from *offset_ptr.
StringRef getCStrRef(Cursor &C) const
Extract a C string (as a StringRef) from the location given by the cursor.
StringRef getBytes(Cursor &C, uint64_t Length)
Extract a fixed number of bytes from the location given by the cursor.
int32_t getS32(Cursor &C) const
Extract a int32_t value from *OffsetPtr.
DataExtractor(ArrayRef< uint8_t > Data, bool IsLittleEndian)
const char * getCStr(Cursor &C) const
Extract a C string from the location given by the cursor.
LLVM_ABI uint16_t getU16(uint64_t *offset_ptr, Error *Err=nullptr) const
Extract a uint16_t value from *offset_ptr.
uint16_t getU16(Cursor &C) const
Extract a single uint16_t value from the location given by the cursor.
LLVM_ABI void skip(Cursor &C, uint64_t Length) const
Advance the Cursor position by the given number of bytes.
APSInt getSLEB128APSInt(Cursor &C) const
Extract an arbitrary-precision signed LEB128 value from the location given by the cursor.
uint64_t getU64(Cursor &C) const
Extract a single uint64_t value from the location given by the cursor.
LLVM_ABI uint64_t getU64(uint64_t *offset_ptr, Error *Err=nullptr) const
Extract a uint64_t value from *offset_ptr.
uint8_t getU8(Cursor &C) const
Extract a single uint8_t value from the location given by the cursor.
static Error & getError(Cursor &C)
int16_t getS16(Cursor &C) const
Extract a int16_t value from *OffsetPtr.
bool isValidOffset(uint64_t offset) const
Test the validity of offset.
bool isValidOffsetForDataOfSize(uint64_t offset, uint64_t length) const
Test the availability of length bytes of data from offset.
bool isLittleEndian() const
Get the endianness for this extractor.
LLVM_ABI StringRef getBytes(uint64_t *OffsetPtr, uint64_t Length, Error *Err=nullptr) const
Extract a fixed number of bytes from the specified offset.
int8_t getS8(Cursor &C) const
Extract a int8_t value from *OffsetPtr.
LLVM_ABI uint32_t getU24(uint64_t *OffsetPtr, Error *Err=nullptr) const
Extract a 24-bit unsigned value from *offset_ptr and return it in a uint32_t.
int64_t getS64(Cursor &C) const
Extract a int64_t value from *OffsetPtr.
LLVM_ABI APSInt getSLEB128APSInt(uint64_t *OffsetPtr, Error *Err=nullptr) const
Extract an arbitrary-precision signed LEB128 value from *OffsetPtr.
Lightweight error class with error context and mandatory checking.
Definition Error.h:159
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
constexpr const char * data() const
Get a pointer to the start of the string (which may not be null terminated).
Definition StringRef.h:138
This is an optimization pass for GlobalISel generic memory operations.
@ Offset
Definition DWP.cpp:577
@ Length
Definition DWP.cpp:577
auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)
Get the size of a range.
Definition STLExtras.h:1669
uint24_t getSwappedBytes(uint24_t C)
Needed by swapByteOrder().
Uint24 uint24_t
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Count
Definition InstrProf.h:145
auto count(R &&Range, const E &Element)
Wrapper function around std::count to count the number of times an element Element occurs in the give...
Definition STLExtras.h:2012
LogicalResult success(bool IsSuccess=true)
Utility function to generate a LogicalResult.
An auxiliary type to facilitate extraction of 3-byte entities.
Uint24(uint8_t U)
uint8_t Bytes[3]
uint32_t getAsUint32(bool IsLittleEndian) const
Uint24(uint8_t U0, uint8_t U1, uint8_t U2)