1//===-- DataExtractor.h -----------------------------------------*- C++ -*-===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef LLVM_SUPPORT_DATAEXTRACTOR_H
11#define LLVM_SUPPORT_DATAEXTRACTOR_H
12
13#include "llvm/ADT/DenseMap.h"
14#include "llvm/ADT/StringRef.h"
15#include "llvm/Support/DataTypes.h"
16
17namespace llvm {
18class DataExtractor {
19  StringRef Data;
20  uint8_t IsLittleEndian;
21  uint8_t AddressSize;
22public:
23  /// Construct with a buffer that is owned by the caller.
24  ///
25  /// This constructor allows us to use data that is owned by the
26  /// caller. The data must stay around as long as this object is
27  /// valid.
28  DataExtractor(StringRef Data, bool IsLittleEndian, uint8_t AddressSize)
29    : Data(Data), IsLittleEndian(IsLittleEndian), AddressSize(AddressSize) {}
30
31  /// \brief Get the data pointed to by this extractor.
32  StringRef getData() const { return Data; }
33  /// \brief Get the endianess for this extractor.
34  bool isLittleEndian() const { return IsLittleEndian; }
35  /// \brief Get the address size for this extractor.
36  uint8_t getAddressSize() const { return AddressSize; }
37  /// \brief Set the address size for this extractor.
38  void setAddressSize(uint8_t Size) { AddressSize = Size; }
39
40  /// Extract a C string from \a *offset_ptr.
41  ///
42  /// Returns a pointer to a C String from the data at the offset
43  /// pointed to by \a offset_ptr. A variable length NULL terminated C
44  /// string will be extracted and the \a offset_ptr will be
45  /// updated with the offset of the byte that follows the NULL
46  /// terminator byte.
47  ///
48  /// @param[in,out] offset_ptr
49  ///     A pointer to an offset within the data that will be advanced
50  ///     by the appropriate number of bytes if the value is extracted
51  ///     correctly. If the offset is out of bounds or there are not
52  ///     enough bytes to extract this value, the offset will be left
53  ///     unmodified.
54  ///
55  /// @return
56  ///     A pointer to the C string value in the data. If the offset
57  ///     pointed to by \a offset_ptr is out of bounds, or if the
58  ///     offset plus the length of the C string is out of bounds,
59  ///     NULL will be returned.
60  const char *getCStr(uint32_t *offset_ptr) const;
61
62  /// Extract an unsigned integer of size \a byte_size from \a
63  /// *offset_ptr.
64  ///
65  /// Extract a single unsigned integer value and update the offset
66  /// pointed to by \a offset_ptr. The size of the extracted integer
67  /// is specified by the \a byte_size argument. \a byte_size should
68  /// have a value greater than or equal to one and less than or equal
69  /// to eight since the return value is 64 bits wide. Any
70  /// \a byte_size values less than 1 or greater than 8 will result in
71  /// nothing being extracted, and zero being returned.
72  ///
73  /// @param[in,out] offset_ptr
74  ///     A pointer to an offset within the data that will be advanced
75  ///     by the appropriate number of bytes if the value is extracted
76  ///     correctly. If the offset is out of bounds or there are not
77  ///     enough bytes to extract this value, the offset will be left
78  ///     unmodified.
79  ///
80  /// @param[in] byte_size
81  ///     The size in byte of the integer to extract.
82  ///
83  /// @return
84  ///     The unsigned integer value that was extracted, or zero on
85  ///     failure.
86  uint64_t getUnsigned(uint32_t *offset_ptr, uint32_t byte_size) const;
87
88  /// Extract an signed integer of size \a byte_size from \a *offset_ptr.
89  ///
90  /// Extract a single signed integer value (sign extending if required)
91  /// and update the offset pointed to by \a offset_ptr. The size of
92  /// the extracted integer is specified by the \a byte_size argument.
93  /// \a byte_size should have a value greater than or equal to one
94  /// and less than or equal to eight since the return value is 64
95  /// bits wide. Any \a byte_size values less than 1 or greater than
96  /// 8 will result in nothing being extracted, and zero being returned.
97  ///
98  /// @param[in,out] offset_ptr
99  ///     A pointer to an offset within the data that will be advanced
100  ///     by the appropriate number of bytes if the value is extracted
101  ///     correctly. If the offset is out of bounds or there are not
102  ///     enough bytes to extract this value, the offset will be left
103  ///     unmodified.
104  ///
105  /// @param[in] size
106  ///     The size in bytes of the integer to extract.
107  ///
108  /// @return
109  ///     The sign extended signed integer value that was extracted,
110  ///     or zero on failure.
111  int64_t getSigned(uint32_t *offset_ptr, uint32_t size) const;
112
113  //------------------------------------------------------------------
114  /// Extract an pointer from \a *offset_ptr.
115  ///
116  /// Extract a single pointer from the data and update the offset
117  /// pointed to by \a offset_ptr. The size of the extracted pointer
118  /// is \a getAddressSize(), so the address size has to be
119  /// set correctly prior to extracting any pointer values.
120  ///
121  /// @param[in,out] offset_ptr
122  ///     A pointer to an offset within the data that will be advanced
123  ///     by the appropriate number of bytes if the value is extracted
124  ///     correctly. If the offset is out of bounds or there are not
125  ///     enough bytes to extract this value, the offset will be left
126  ///     unmodified.
127  ///
128  /// @return
129  ///     The extracted pointer value as a 64 integer.
130  uint64_t getAddress(uint32_t *offset_ptr) const {
131    return getUnsigned(offset_ptr, AddressSize);
132  }
133
134  /// Extract a uint8_t value from \a *offset_ptr.
135  ///
136  /// Extract a single uint8_t from the binary data at the offset
137  /// pointed to by \a offset_ptr, and advance the offset on success.
138  ///
139  /// @param[in,out] offset_ptr
140  ///     A pointer to an offset within the data that will be advanced
141  ///     by the appropriate number of bytes if the value is extracted
142  ///     correctly. If the offset is out of bounds or there are not
143  ///     enough bytes to extract this value, the offset will be left
144  ///     unmodified.
145  ///
146  /// @return
147  ///     The extracted uint8_t value.
148  uint8_t getU8(uint32_t *offset_ptr) const;
149
150  /// Extract \a count uint8_t values from \a *offset_ptr.
151  ///
152  /// Extract \a count uint8_t values from the binary data at the
153  /// offset pointed to by \a offset_ptr, and advance the offset on
154  /// success. The extracted values are copied into \a dst.
155  ///
156  /// @param[in,out] offset_ptr
157  ///     A pointer to an offset within the data that will be advanced
158  ///     by the appropriate number of bytes if the value is extracted
159  ///     correctly. If the offset is out of bounds or there are not
160  ///     enough bytes to extract this value, the offset will be left
161  ///     unmodified.
162  ///
163  /// @param[out] dst
164  ///     A buffer to copy \a count uint8_t values into. \a dst must
165  ///     be large enough to hold all requested data.
166  ///
167  /// @param[in] count
168  ///     The number of uint8_t values to extract.
169  ///
170  /// @return
171  ///     \a dst if all values were properly extracted and copied,
172  ///     NULL otherise.
173  uint8_t *getU8(uint32_t *offset_ptr, uint8_t *dst, uint32_t count) const;
174
175  //------------------------------------------------------------------
176  /// Extract a uint16_t value from \a *offset_ptr.
177  ///
178  /// Extract a single uint16_t from the binary data at the offset
179  /// pointed to by \a offset_ptr, and update the offset on success.
180  ///
181  /// @param[in,out] offset_ptr
182  ///     A pointer to an offset within the data that will be advanced
183  ///     by the appropriate number of bytes if the value is extracted
184  ///     correctly. If the offset is out of bounds or there are not
185  ///     enough bytes to extract this value, the offset will be left
186  ///     unmodified.
187  ///
188  /// @return
189  ///     The extracted uint16_t value.
190  //------------------------------------------------------------------
191  uint16_t getU16(uint32_t *offset_ptr) const;
192
193  /// Extract \a count uint16_t values from \a *offset_ptr.
194  ///
195  /// Extract \a count uint16_t values from the binary data at the
196  /// offset pointed to by \a offset_ptr, and advance the offset on
197  /// success. The extracted values are copied into \a dst.
198  ///
199  /// @param[in,out] offset_ptr
200  ///     A pointer to an offset within the data that will be advanced
201  ///     by the appropriate number of bytes if the value is extracted
202  ///     correctly. If the offset is out of bounds or there are not
203  ///     enough bytes to extract this value, the offset will be left
204  ///     unmodified.
205  ///
206  /// @param[out] dst
207  ///     A buffer to copy \a count uint16_t values into. \a dst must
208  ///     be large enough to hold all requested data.
209  ///
210  /// @param[in] count
211  ///     The number of uint16_t values to extract.
212  ///
213  /// @return
214  ///     \a dst if all values were properly extracted and copied,
215  ///     NULL otherise.
216  uint16_t *getU16(uint32_t *offset_ptr, uint16_t *dst, uint32_t count) const;
217
218  /// Extract a uint32_t value from \a *offset_ptr.
219  ///
220  /// Extract a single uint32_t from the binary data at the offset
221  /// pointed to by \a offset_ptr, and update the offset on success.
222  ///
223  /// @param[in,out] offset_ptr
224  ///     A pointer to an offset within the data that will be advanced
225  ///     by the appropriate number of bytes if the value is extracted
226  ///     correctly. If the offset is out of bounds or there are not
227  ///     enough bytes to extract this value, the offset will be left
228  ///     unmodified.
229  ///
230  /// @return
231  ///     The extracted uint32_t value.
232  uint32_t getU32(uint32_t *offset_ptr) const;
233
234  /// Extract \a count uint32_t values from \a *offset_ptr.
235  ///
236  /// Extract \a count uint32_t values from the binary data at the
237  /// offset pointed to by \a offset_ptr, and advance the offset on
238  /// success. The extracted values are copied into \a dst.
239  ///
240  /// @param[in,out] offset_ptr
241  ///     A pointer to an offset within the data that will be advanced
242  ///     by the appropriate number of bytes if the value is extracted
243  ///     correctly. If the offset is out of bounds or there are not
244  ///     enough bytes to extract this value, the offset will be left
245  ///     unmodified.
246  ///
247  /// @param[out] dst
248  ///     A buffer to copy \a count uint32_t values into. \a dst must
249  ///     be large enough to hold all requested data.
250  ///
251  /// @param[in] count
252  ///     The number of uint32_t values to extract.
253  ///
254  /// @return
255  ///     \a dst if all values were properly extracted and copied,
256  ///     NULL otherise.
257  uint32_t *getU32(uint32_t *offset_ptr, uint32_t *dst, uint32_t count) const;
258
259  /// Extract a uint64_t value from \a *offset_ptr.
260  ///
261  /// Extract a single uint64_t from the binary data at the offset
262  /// pointed to by \a offset_ptr, and update the offset on success.
263  ///
264  /// @param[in,out] offset_ptr
265  ///     A pointer to an offset within the data that will be advanced
266  ///     by the appropriate number of bytes if the value is extracted
267  ///     correctly. If the offset is out of bounds or there are not
268  ///     enough bytes to extract this value, the offset will be left
269  ///     unmodified.
270  ///
271  /// @return
272  ///     The extracted uint64_t value.
273  uint64_t getU64(uint32_t *offset_ptr) const;
274
275  /// Extract \a count uint64_t values from \a *offset_ptr.
276  ///
277  /// Extract \a count uint64_t values from the binary data at the
278  /// offset pointed to by \a offset_ptr, and advance the offset on
279  /// success. The extracted values are copied into \a dst.
280  ///
281  /// @param[in,out] offset_ptr
282  ///     A pointer to an offset within the data that will be advanced
283  ///     by the appropriate number of bytes if the value is extracted
284  ///     correctly. If the offset is out of bounds or there are not
285  ///     enough bytes to extract this value, the offset will be left
286  ///     unmodified.
287  ///
288  /// @param[out] dst
289  ///     A buffer to copy \a count uint64_t values into. \a dst must
290  ///     be large enough to hold all requested data.
291  ///
292  /// @param[in] count
293  ///     The number of uint64_t values to extract.
294  ///
295  /// @return
296  ///     \a dst if all values were properly extracted and copied,
297  ///     NULL otherise.
298  uint64_t *getU64(uint32_t *offset_ptr, uint64_t *dst, uint32_t count) const;
299
300  /// Extract a signed LEB128 value from \a *offset_ptr.
301  ///
302  /// Extracts an signed LEB128 number from this object's data
303  /// starting at the offset pointed to by \a offset_ptr. The offset
304  /// pointed to by \a offset_ptr will be updated with the offset of
305  /// the byte following the last extracted byte.
306  ///
307  /// @param[in,out] offset_ptr
308  ///     A pointer to an offset within the data that will be advanced
309  ///     by the appropriate number of bytes if the value is extracted
310  ///     correctly. If the offset is out of bounds or there are not
311  ///     enough bytes to extract this value, the offset will be left
312  ///     unmodified.
313  ///
314  /// @return
315  ///     The extracted signed integer value.
316  int64_t getSLEB128(uint32_t *offset_ptr) const;
317
318  /// Extract a unsigned LEB128 value from \a *offset_ptr.
319  ///
320  /// Extracts an unsigned LEB128 number from this object's data
321  /// starting at the offset pointed to by \a offset_ptr. The offset
322  /// pointed to by \a offset_ptr will be updated with the offset of
323  /// the byte following the last extracted byte.
324  ///
325  /// @param[in,out] offset_ptr
326  ///     A pointer to an offset within the data that will be advanced
327  ///     by the appropriate number of bytes if the value is extracted
328  ///     correctly. If the offset is out of bounds or there are not
329  ///     enough bytes to extract this value, the offset will be left
330  ///     unmodified.
331  ///
332  /// @return
333  ///     The extracted unsigned integer value.
334  uint64_t getULEB128(uint32_t *offset_ptr) const;
335
336  /// Test the validity of \a offset.
337  ///
338  /// @return
339  ///     \b true if \a offset is a valid offset into the data in this
340  ///     object, \b false otherwise.
341  bool isValidOffset(uint32_t offset) const { return Data.size() > offset; }
342
343  /// Test the availability of \a length bytes of data from \a offset.
344  ///
345  /// @return
346  ///     \b true if \a offset is a valid offset and there are \a
347  ///     length bytes available at that offset, \b false otherwise.
348  bool isValidOffsetForDataOfSize(uint32_t offset, uint32_t length) const {
349    return offset + length >= offset && isValidOffset(offset + length - 1);
350  }
351};
352
353} // namespace llvm
354
355#endif
356