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