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
16namespace llvm {
17
18/// An auxiliary type to facilitate extraction of 3-byte entities.
19struct 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
33using uint24_t = Uint24;
34static_assert(sizeof(uint24_t) == 3, "sizeof(uint24_t) != 3");
35
36/// Needed by swapByteOrder().
37inline uint24_t getSwappedBytes(uint24_t C) {
38  return uint24_t(C.Bytes[2], C.Bytes[1], C.Bytes[0]);
39}
40
41class DataExtractor {
42  StringRef Data;
43  uint8_t IsLittleEndian;
44  uint8_t AddressSize;
45public:
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.
166  StringRef getCStrRef(Cursor &C) const {
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
687protected:
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
693private:
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
707