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];
Uint24Uint2421   Uint24(uint8_t U) {
22     Bytes[0] = Bytes[1] = Bytes[2] = U;
23   }
Uint24Uint2424   Uint24(uint8_t U0, uint8_t U1, uint8_t U2) {
25     Bytes[0] = U0; Bytes[1] = U1; Bytes[2] = U2;
26   }
getAsUint32Uint2427   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().
getSwappedBytes(uint24_t C)37 inline uint24_t getSwappedBytes(uint24_t C) {
38   return uint24_t(C.Bytes[2], C.Bytes[1], C.Bytes[0]);
39 }
40 
41 class DataExtractor {
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.
Cursor(uint64_t 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.
tell()71     uint64_t tell() const { return Offset; }
72 
73     /// Set the cursor to the new offset. This does not impact the error state.
seek(uint64_t NewOffSet)74     void seek(uint64_t NewOffSet) { Offset = NewOffSet; }
75 
76     /// Return error contained inside this Cursor, if any. Clears the internal
77     /// Cursor state.
takeError()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.
DataExtractor(StringRef Data,bool IsLittleEndian,uint8_t AddressSize)86   DataExtractor(StringRef Data, bool IsLittleEndian, uint8_t AddressSize)
87     : Data(Data), IsLittleEndian(IsLittleEndian), AddressSize(AddressSize) {}
DataExtractor(ArrayRef<uint8_t> Data,bool IsLittleEndian,uint8_t 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.
getData()95   StringRef getData() const { return Data; }
96   /// Get the endianness for this extractor.
isLittleEndian()97   bool isLittleEndian() const { return IsLittleEndian; }
98   /// Get the address size for this extractor.
getAddressSize()99   uint8_t getAddressSize() const { return AddressSize; }
100   /// Set the address size for this extractor.
setAddressSize(uint8_t Size)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.
getCStr(Cursor & C)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.
getCStrRef(Cursor & C)169   StringRef getCStrRef(Cursor &C) const {
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.
203   StringRef getFixedLengthString(uint64_t *OffsetPtr,
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.
getBytes(Cursor & C,uint64_t Length)239   StringRef getBytes(Cursor &C, uint64_t Length) {
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.
getUnsigned(Cursor & C,uint32_t Size)279   uint64_t getUnsigned(Cursor &C, uint32_t Size) const {
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.
getAddress(uint64_t * offset_ptr)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.
getAddress(Cursor & C)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.
getU8(Cursor & C)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.
getU8(Cursor & C,SmallVectorImpl<uint8_t> & Dst,uint32_t Count)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.
getU16(Cursor & C)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.
getU24(Cursor & C)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.
getU32(Cursor & C)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.
getU64(Cursor & C)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.
getSLEB128(Cursor & C)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.
getULEB128(Cursor & C)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.
eof(const Cursor & C)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.
isValidOffset(uint64_t offset)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.
isValidOffsetForDataOfSize(uint64_t offset,uint64_t length)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.
isValidOffsetForAddress(uint64_t offset)683   bool isValidOffsetForAddress(uint64_t offset) const {
684     return isValidOffsetForDataOfSize(offset, AddressSize);
685   }
686 
687   /// Return the number of bytes in the underlying buffer.
size()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.
getOffset(Cursor & C)693   static uint64_t &getOffset(Cursor &C) { return C.Offset; }
getError(Cursor & C)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
710