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