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