Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
14 pmbaty 1
//===-- DataExtractor.h -----------------------------------------*- C++ -*-===//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
 
9
#ifndef LLVM_SUPPORT_DATAEXTRACTOR_H
10
#define LLVM_SUPPORT_DATAEXTRACTOR_H
11
 
12
#include "llvm/ADT/StringRef.h"
13
#include "llvm/Support/DataTypes.h"
14
#include "llvm/Support/Error.h"
15
 
16
namespace llvm {
17
 
18
/// An auxiliary type to facilitate extraction of 3-byte entities.
19
struct Uint24 {
20
  uint8_t Bytes[3];
21
  Uint24(uint8_t U) {
22
    Bytes[0] = Bytes[1] = Bytes[2] = U;
23
  }
24
  Uint24(uint8_t U0, uint8_t U1, uint8_t U2) {
25
    Bytes[0] = U0; Bytes[1] = U1; Bytes[2] = U2;
26
  }
27
  uint32_t getAsUint32(bool IsLittleEndian) const {
28
    int LoIx = IsLittleEndian ? 0 : 2;
29
    return Bytes[LoIx] + (Bytes[1] << 8) + (Bytes[2-LoIx] << 16);
30
  }
31
};
32
 
33
using uint24_t = Uint24;
34
static_assert(sizeof(uint24_t) == 3, "sizeof(uint24_t) != 3");
35
 
36
/// Needed by swapByteOrder().
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.
62
    explicit Cursor(uint64_t Offset) : Offset(Offset), Err(Error::success()) {}
63
 
64
    /// Checks whether the cursor is valid (i.e. no errors were encountered). In
65
    /// case of errors, this does not clear the error flag -- one must call
66
    /// takeError() instead.
67
    explicit operator bool() { return !Err; }
68
 
69
    /// Return the current position of this Cursor. In the error state this is
70
    /// the position of the Cursor before the first error was encountered.
71
    uint64_t tell() const { return Offset; }
72
 
73
    /// Set the cursor to the new offset. This does not impact the error state.
74
    void seek(uint64_t NewOffSet) { Offset = NewOffSet; }
75
 
76
    /// Return error contained inside this Cursor, if any. Clears the internal
77
    /// Cursor state.
78
    Error takeError() { return std::move(Err); }
79
  };
80
 
81
  /// Construct with a buffer that is owned by the caller.
82
  ///
83
  /// This constructor allows us to use data that is owned by the
84
  /// caller. The data must stay around as long as this object is
85
  /// valid.
86
  DataExtractor(StringRef Data, bool IsLittleEndian, uint8_t AddressSize)
87
    : Data(Data), IsLittleEndian(IsLittleEndian), AddressSize(AddressSize) {}
88
  DataExtractor(ArrayRef<uint8_t> Data, bool IsLittleEndian,
89
                uint8_t AddressSize)
90
      : Data(StringRef(reinterpret_cast<const char *>(Data.data()),
91
                       Data.size())),
92
        IsLittleEndian(IsLittleEndian), AddressSize(AddressSize) {}
93
 
94
  /// Get the data pointed to by this extractor.
95
  StringRef getData() const { return Data; }
96
  /// Get the endianness for this extractor.
97
  bool isLittleEndian() const { return IsLittleEndian; }
98
  /// Get the address size for this extractor.
99
  uint8_t getAddressSize() const { return AddressSize; }
100
  /// Set the address size for this extractor.
101
  void setAddressSize(uint8_t Size) { AddressSize = Size; }
102
 
103
  /// Extract a C string from \a *offset_ptr.
104
  ///
105
  /// Returns a pointer to a C String from the data at the offset
106
  /// pointed to by \a offset_ptr. A variable length NULL terminated C
107
  /// string will be extracted and the \a offset_ptr will be
108
  /// updated with the offset of the byte that follows the NULL
109
  /// terminator byte.
110
  ///
111
  /// @param[in,out] OffsetPtr
112
  ///     A pointer to an offset within the data that will be advanced
113
  ///     by the appropriate number of bytes if the value is extracted
114
  ///     correctly. If the offset is out of bounds or there are not
115
  ///     enough bytes to extract this value, the offset will be left
116
  ///     unmodified.
117
  ///
118
  /// @param[in,out] Err
119
  ///     A pointer to an Error object. Upon return the Error object is set to
120
  ///     indicate the result (success/failure) of the function. If the Error
121
  ///     object is already set when calling this function, no extraction is
122
  ///     performed.
123
  ///
124
  /// @return
125
  ///     A pointer to the C string value in the data. If the offset
126
  ///     pointed to by \a offset_ptr is out of bounds, or if the
127
  ///     offset plus the length of the C string is out of bounds,
128
  ///     NULL will be returned.
129
  const char *getCStr(uint64_t *OffsetPtr, Error *Err = nullptr) const {
130
    return getCStrRef(OffsetPtr, Err).data();
131
  }
132
 
133
  /// Extract a C string from the location given by the cursor. In case of an
134
  /// extraction error, or if the cursor is already in an error state, a
135
  /// nullptr is returned.
136
  const char *getCStr(Cursor &C) const { return getCStrRef(C).data(); }
137
 
138
  /// Extract a C string from \a *offset_ptr.
139
  ///
140
  /// Returns a StringRef for the C String from the data at the offset
141
  /// pointed to by \a offset_ptr. A variable length NULL terminated C
142
  /// string will be extracted and the \a offset_ptr will be
143
  /// updated with the offset of the byte that follows the NULL
144
  /// terminator byte.
145
  ///
146
  /// \param[in,out] OffsetPtr
147
  ///     A pointer to an offset within the data that will be advanced
148
  ///     by the appropriate number of bytes if the value is extracted
149
  ///     correctly. If the offset is out of bounds or there are not
150
  ///     enough bytes to extract this value, the offset will be left
151
  ///     unmodified.
152
  ///
153
  /// @param[in,out] Err
154
  ///     A pointer to an Error object. Upon return the Error object is set to
155
  ///     indicate the result (success/failure) of the function. If the Error
156
  ///     object is already set when calling this function, no extraction is
157
  ///     performed.
158
  ///
159
  /// \return
160
  ///     A StringRef for the C string value in the data. If the offset
161
  ///     pointed to by \a offset_ptr is out of bounds, or if the
162
  ///     offset plus the length of the C string is out of bounds,
163
  ///     a default-initialized StringRef will be returned.
164
  StringRef getCStrRef(uint64_t *OffsetPtr, Error *Err = nullptr) const;
165
 
166
  /// Extract a C string (as a StringRef) from the location given by the cursor.
167
  /// In case of an extraction error, or if the cursor is already in an error
168
  /// state, a default-initialized StringRef is returned.
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.
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.
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.
325
  uint64_t getAddress(uint64_t *offset_ptr) const {
326
    return getUnsigned(offset_ptr, AddressSize);
327
  }
328
 
329
  /// Extract a pointer-sized unsigned integer from the location given by the
330
  /// cursor. In case of an extraction error, or if the cursor is already in
331
  /// an error state, zero is returned.
332
  uint64_t getAddress(Cursor &C) const { return getUnsigned(C, AddressSize); }
333
 
334
  /// Extract a uint8_t value from \a *offset_ptr.
335
  ///
336
  /// Extract a single uint8_t from the binary data at the offset
337
  /// pointed to by \a offset_ptr, and advance the offset on success.
338
  ///
339
  /// @param[in,out] offset_ptr
340
  ///     A pointer to an offset within the data that will be advanced
341
  ///     by the appropriate number of bytes if the value is extracted
342
  ///     correctly. If the offset is out of bounds or there are not
343
  ///     enough bytes to extract this value, the offset will be left
344
  ///     unmodified.
345
  ///
346
  /// @param[in,out] Err
347
  ///     A pointer to an Error object. Upon return the Error object is set to
348
  ///     indicate the result (success/failure) of the function. If the Error
349
  ///     object is already set when calling this function, no extraction is
350
  ///     performed.
351
  ///
352
  /// @return
353
  ///     The extracted uint8_t value.
354
  uint8_t getU8(uint64_t *offset_ptr, Error *Err = nullptr) const;
355
 
356
  /// Extract a single uint8_t value from the location given by the cursor. In
357
  /// case of an extraction error, or if the cursor is already in an error
358
  /// state, zero is returned.
359
  uint8_t getU8(Cursor &C) const { return getU8(&C.Offset, &C.Err); }
360
 
361
  /// Extract \a count uint8_t values from \a *offset_ptr.
362
  ///
363
  /// Extract \a count uint8_t values from the binary data at the
364
  /// offset pointed to by \a offset_ptr, and advance the offset on
365
  /// success. The extracted values are copied into \a dst.
366
  ///
367
  /// @param[in,out] offset_ptr
368
  ///     A pointer to an offset within the data that will be advanced
369
  ///     by the appropriate number of bytes if the value is extracted
370
  ///     correctly. If the offset is out of bounds or there are not
371
  ///     enough bytes to extract this value, the offset will be left
372
  ///     unmodified.
373
  ///
374
  /// @param[out] dst
375
  ///     A buffer to copy \a count uint8_t values into. \a dst must
376
  ///     be large enough to hold all requested data.
377
  ///
378
  /// @param[in] count
379
  ///     The number of uint8_t values to extract.
380
  ///
381
  /// @return
382
  ///     \a dst if all values were properly extracted and copied,
383
  ///     NULL otherise.
384
  uint8_t *getU8(uint64_t *offset_ptr, uint8_t *dst, uint32_t count) const;
385
 
386
  /// Extract \a Count uint8_t values from the location given by the cursor and
387
  /// store them into the destination buffer. In case of an extraction error, or
388
  /// if the cursor is already in an error state, a nullptr is returned and the
389
  /// destination buffer is left unchanged.
390
  uint8_t *getU8(Cursor &C, uint8_t *Dst, uint32_t Count) const;
391
 
392
  /// Extract \a Count uint8_t values from the location given by the cursor and
393
  /// store them into the destination vector. The vector is resized to fit the
394
  /// extracted data. In case of an extraction error, or if the cursor is
395
  /// already in an error state, the destination vector is left unchanged and
396
  /// cursor is placed into an error state.
397
  void getU8(Cursor &C, SmallVectorImpl<uint8_t> &Dst, uint32_t Count) const {
398
    if (isValidOffsetForDataOfSize(C.Offset, Count))
399
      Dst.resize(Count);
400
 
401
    // This relies on the fact that getU8 will not attempt to write to the
402
    // buffer if isValidOffsetForDataOfSize(C.Offset, Count) is false.
403
    getU8(C, Dst.data(), Count);
404
  }
405
 
406
  //------------------------------------------------------------------
407
  /// Extract a uint16_t value from \a *offset_ptr.
408
  ///
409
  /// Extract a single uint16_t from the binary data at the offset
410
  /// pointed to by \a offset_ptr, and update the offset on success.
411
  ///
412
  /// @param[in,out] offset_ptr
413
  ///     A pointer to an offset within the data that will be advanced
414
  ///     by the appropriate number of bytes if the value is extracted
415
  ///     correctly. If the offset is out of bounds or there are not
416
  ///     enough bytes to extract this value, the offset will be left
417
  ///     unmodified.
418
  ///
419
  /// @param[in,out] Err
420
  ///     A pointer to an Error object. Upon return the Error object is set to
421
  ///     indicate the result (success/failure) of the function. If the Error
422
  ///     object is already set when calling this function, no extraction is
423
  ///     performed.
424
  ///
425
  /// @return
426
  ///     The extracted uint16_t value.
427
  //------------------------------------------------------------------
428
  uint16_t getU16(uint64_t *offset_ptr, Error *Err = nullptr) const;
429
 
430
  /// Extract a single uint16_t value from the location given by the cursor. In
431
  /// case of an extraction error, or if the cursor is already in an error
432
  /// state, zero is returned.
433
  uint16_t getU16(Cursor &C) const { return getU16(&C.Offset, &C.Err); }
434
 
435
  /// Extract \a count uint16_t values from \a *offset_ptr.
436
  ///
437
  /// Extract \a count uint16_t values from the binary data at the
438
  /// offset pointed to by \a offset_ptr, and advance the offset on
439
  /// success. The extracted values are copied into \a dst.
440
  ///
441
  /// @param[in,out] offset_ptr
442
  ///     A pointer to an offset within the data that will be advanced
443
  ///     by the appropriate number of bytes if the value is extracted
444
  ///     correctly. If the offset is out of bounds or there are not
445
  ///     enough bytes to extract this value, the offset will be left
446
  ///     unmodified.
447
  ///
448
  /// @param[out] dst
449
  ///     A buffer to copy \a count uint16_t values into. \a dst must
450
  ///     be large enough to hold all requested data.
451
  ///
452
  /// @param[in] count
453
  ///     The number of uint16_t values to extract.
454
  ///
455
  /// @return
456
  ///     \a dst if all values were properly extracted and copied,
457
  ///     NULL otherise.
458
  uint16_t *getU16(uint64_t *offset_ptr, uint16_t *dst, uint32_t count) const;
459
 
460
  /// Extract a 24-bit unsigned value from \a *offset_ptr and return it
461
  /// in a uint32_t.
462
  ///
463
  /// Extract 3 bytes from the binary data at the offset pointed to by
464
  /// \a offset_ptr, construct a uint32_t from them and update the offset
465
  /// on success.
466
  ///
467
  /// @param[in,out] OffsetPtr
468
  ///     A pointer to an offset within the data that will be advanced
469
  ///     by the 3 bytes if the value is extracted correctly. If the offset
470
  ///     is out of bounds or there are not enough bytes to extract this value,
471
  ///     the offset will be left unmodified.
472
  ///
473
  /// @param[in,out] Err
474
  ///     A pointer to an Error object. Upon return the Error object is set to
475
  ///     indicate the result (success/failure) of the function. If the Error
476
  ///     object is already set when calling this function, no extraction is
477
  ///     performed.
478
  ///
479
  /// @return
480
  ///     The extracted 24-bit value represented in a uint32_t.
481
  uint32_t getU24(uint64_t *OffsetPtr, Error *Err = nullptr) const;
482
 
483
  /// Extract a single 24-bit unsigned value from the location given by the
484
  /// cursor. In case of an extraction error, or if the cursor is already in an
485
  /// error state, zero is returned.
486
  uint32_t getU24(Cursor &C) const { return getU24(&C.Offset, &C.Err); }
487
 
488
  /// Extract a uint32_t value from \a *offset_ptr.
489
  ///
490
  /// Extract a single uint32_t from the binary data at the offset
491
  /// pointed to by \a offset_ptr, and update the offset on success.
492
  ///
493
  /// @param[in,out] offset_ptr
494
  ///     A pointer to an offset within the data that will be advanced
495
  ///     by the appropriate number of bytes if the value is extracted
496
  ///     correctly. If the offset is out of bounds or there are not
497
  ///     enough bytes to extract this value, the offset will be left
498
  ///     unmodified.
499
  ///
500
  /// @param[in,out] Err
501
  ///     A pointer to an Error object. Upon return the Error object is set to
502
  ///     indicate the result (success/failure) of the function. If the Error
503
  ///     object is already set when calling this function, no extraction is
504
  ///     performed.
505
  ///
506
  /// @return
507
  ///     The extracted uint32_t value.
508
  uint32_t getU32(uint64_t *offset_ptr, Error *Err = nullptr) const;
509
 
510
  /// Extract a single uint32_t value from the location given by the cursor. In
511
  /// case of an extraction error, or if the cursor is already in an error
512
  /// state, zero is returned.
513
  uint32_t getU32(Cursor &C) const { return getU32(&C.Offset, &C.Err); }
514
 
515
  /// Extract \a count uint32_t values from \a *offset_ptr.
516
  ///
517
  /// Extract \a count uint32_t values from the binary data at the
518
  /// offset pointed to by \a offset_ptr, and advance the offset on
519
  /// success. The extracted values are copied into \a dst.
520
  ///
521
  /// @param[in,out] offset_ptr
522
  ///     A pointer to an offset within the data that will be advanced
523
  ///     by the appropriate number of bytes if the value is extracted
524
  ///     correctly. If the offset is out of bounds or there are not
525
  ///     enough bytes to extract this value, the offset will be left
526
  ///     unmodified.
527
  ///
528
  /// @param[out] dst
529
  ///     A buffer to copy \a count uint32_t values into. \a dst must
530
  ///     be large enough to hold all requested data.
531
  ///
532
  /// @param[in] count
533
  ///     The number of uint32_t values to extract.
534
  ///
535
  /// @return
536
  ///     \a dst if all values were properly extracted and copied,
537
  ///     NULL otherise.
538
  uint32_t *getU32(uint64_t *offset_ptr, uint32_t *dst, uint32_t count) const;
539
 
540
  /// Extract a uint64_t value from \a *offset_ptr.
541
  ///
542
  /// Extract a single uint64_t from the binary data at the offset
543
  /// pointed to by \a offset_ptr, and update the offset on success.
544
  ///
545
  /// @param[in,out] offset_ptr
546
  ///     A pointer to an offset within the data that will be advanced
547
  ///     by the appropriate number of bytes if the value is extracted
548
  ///     correctly. If the offset is out of bounds or there are not
549
  ///     enough bytes to extract this value, the offset will be left
550
  ///     unmodified.
551
  ///
552
  /// @param[in,out] Err
553
  ///     A pointer to an Error object. Upon return the Error object is set to
554
  ///     indicate the result (success/failure) of the function. If the Error
555
  ///     object is already set when calling this function, no extraction is
556
  ///     performed.
557
  ///
558
  /// @return
559
  ///     The extracted uint64_t value.
560
  uint64_t getU64(uint64_t *offset_ptr, Error *Err = nullptr) const;
561
 
562
  /// Extract a single uint64_t value from the location given by the cursor. In
563
  /// case of an extraction error, or if the cursor is already in an error
564
  /// state, zero is returned.
565
  uint64_t getU64(Cursor &C) const { return getU64(&C.Offset, &C.Err); }
566
 
567
  /// Extract \a count uint64_t values from \a *offset_ptr.
568
  ///
569
  /// Extract \a count uint64_t values from the binary data at the
570
  /// offset pointed to by \a offset_ptr, and advance the offset on
571
  /// success. The extracted values are copied into \a dst.
572
  ///
573
  /// @param[in,out] offset_ptr
574
  ///     A pointer to an offset within the data that will be advanced
575
  ///     by the appropriate number of bytes if the value is extracted
576
  ///     correctly. If the offset is out of bounds or there are not
577
  ///     enough bytes to extract this value, the offset will be left
578
  ///     unmodified.
579
  ///
580
  /// @param[out] dst
581
  ///     A buffer to copy \a count uint64_t values into. \a dst must
582
  ///     be large enough to hold all requested data.
583
  ///
584
  /// @param[in] count
585
  ///     The number of uint64_t values to extract.
586
  ///
587
  /// @return
588
  ///     \a dst if all values were properly extracted and copied,
589
  ///     NULL otherise.
590
  uint64_t *getU64(uint64_t *offset_ptr, uint64_t *dst, uint32_t count) const;
591
 
592
  /// Extract a signed LEB128 value from \a *offset_ptr.
593
  ///
594
  /// Extracts an signed LEB128 number from this object's data
595
  /// starting at the offset pointed to by \a offset_ptr. The offset
596
  /// pointed to by \a offset_ptr will be updated with the offset of
597
  /// the byte following the last extracted byte.
598
  ///
599
  /// @param[in,out] OffsetPtr
600
  ///     A pointer to an offset within the data that will be advanced
601
  ///     by the appropriate number of bytes if the value is extracted
602
  ///     correctly. If the offset is out of bounds or there are not
603
  ///     enough bytes to extract this value, the offset will be left
604
  ///     unmodified.
605
  ///
606
  /// @param[in,out] Err
607
  ///     A pointer to an Error object. Upon return the Error object is set to
608
  ///     indicate the result (success/failure) of the function. If the Error
609
  ///     object is already set when calling this function, no extraction is
610
  ///     performed.
611
  ///
612
  /// @return
613
  ///     The extracted signed integer value.
614
  int64_t getSLEB128(uint64_t *OffsetPtr, Error *Err = nullptr) const;
615
 
616
  /// Extract an signed LEB128 value from the location given by the cursor.
617
  /// In case of an extraction error, or if the cursor is already in an error
618
  /// state, zero is returned.
619
  int64_t getSLEB128(Cursor &C) const { return getSLEB128(&C.Offset, &C.Err); }
620
 
621
  /// Extract a unsigned LEB128 value from \a *offset_ptr.
622
  ///
623
  /// Extracts an unsigned LEB128 number from this object's data
624
  /// starting at the offset pointed to by \a offset_ptr. The offset
625
  /// pointed to by \a offset_ptr will be updated with the offset of
626
  /// the byte following the last extracted byte.
627
  ///
628
  /// @param[in,out] offset_ptr
629
  ///     A pointer to an offset within the data that will be advanced
630
  ///     by the appropriate number of bytes if the value is extracted
631
  ///     correctly. If the offset is out of bounds or there are not
632
  ///     enough bytes to extract this value, the offset will be left
633
  ///     unmodified.
634
  ///
635
  /// @param[in,out] Err
636
  ///     A pointer to an Error object. Upon return the Error object is set to
637
  ///     indicate the result (success/failure) of the function. If the Error
638
  ///     object is already set when calling this function, no extraction is
639
  ///     performed.
640
  ///
641
  /// @return
642
  ///     The extracted unsigned integer value.
643
  uint64_t getULEB128(uint64_t *offset_ptr, llvm::Error *Err = nullptr) const;
644
 
645
  /// Extract an unsigned LEB128 value from the location given by the cursor.
646
  /// In case of an extraction error, or if the cursor is already in an error
647
  /// state, zero is returned.
648
  uint64_t getULEB128(Cursor &C) const { return getULEB128(&C.Offset, &C.Err); }
649
 
650
  /// Advance the Cursor position by the given number of bytes. No-op if the
651
  /// cursor is in an error state.
652
  void skip(Cursor &C, uint64_t Length) const;
653
 
654
  /// Return true iff the cursor is at the end of the buffer, regardless of the
655
  /// error state of the cursor. The only way both eof and error states can be
656
  /// true is if one attempts a read while the cursor is at the very end of the
657
  /// data buffer.
658
  bool eof(const Cursor &C) const { return size() == C.Offset; }
659
 
660
  /// Test the validity of \a offset.
661
  ///
662
  /// @return
663
  ///     \b true if \a offset is a valid offset into the data in this
664
  ///     object, \b false otherwise.
665
  bool isValidOffset(uint64_t offset) const { return size() > offset; }
666
 
667
  /// Test the availability of \a length bytes of data from \a offset.
668
  ///
669
  /// @return
670
  ///     \b true if \a offset is a valid offset and there are \a
671
  ///     length bytes available at that offset, \b false otherwise.
672
  bool isValidOffsetForDataOfSize(uint64_t offset, uint64_t length) const {
673
    return offset + length >= offset && isValidOffset(offset + length - 1);
674
  }
675
 
676
  /// Test the availability of enough bytes of data for a pointer from
677
  /// \a offset. The size of a pointer is \a getAddressSize().
678
  ///
679
  /// @return
680
  ///     \b true if \a offset is a valid offset and there are enough
681
  ///     bytes for a pointer available at that offset, \b false
682
  ///     otherwise.
683
  bool isValidOffsetForAddress(uint64_t offset) const {
684
    return isValidOffsetForDataOfSize(offset, AddressSize);
685
  }
686
 
687
  /// Return the number of bytes in the underlying buffer.
688
  size_t size() const { return Data.size(); }
689
 
690
protected:
691
  // Make it possible for subclasses to access these fields without making them
692
  // public.
693
  static uint64_t &getOffset(Cursor &C) { return C.Offset; }
694
  static Error &getError(Cursor &C) { return C.Err; }
695
 
696
private:
697
  /// If it is possible to read \a Size bytes at offset \a Offset, returns \b
698
  /// true. Otherwise, returns \b false. If \a E is not nullptr, also sets the
699
  /// error object to indicate an error.
700
  bool prepareRead(uint64_t Offset, uint64_t Size, Error *E) const;
701
 
702
  template <typename T> T getU(uint64_t *OffsetPtr, Error *Err) const;
703
  template <typename T>
704
  T *getUs(uint64_t *OffsetPtr, T *Dst, uint32_t Count, Error *Err) const;
705
};
706
 
707
} // namespace llvm
708
 
709
#endif