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