LLVM  10.0.0svn
DataExtractor.cpp
Go to the documentation of this file.
1 //===-- DataExtractor.cpp -------------------------------------------------===//
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 
11 #include "llvm/Support/Host.h"
13 #include "llvm/Support/LEB128.h"
14 using namespace llvm;
15 
16 template <typename T>
17 static T getU(uint32_t *offset_ptr, const DataExtractor *de,
18  bool isLittleEndian, const char *Data) {
19  T val = 0;
20  uint32_t offset = *offset_ptr;
21  if (de->isValidOffsetForDataOfSize(offset, sizeof(val))) {
22  std::memcpy(&val, &Data[offset], sizeof(val));
23  if (sys::IsLittleEndianHost != isLittleEndian)
24  sys::swapByteOrder(val);
25 
26  // Advance the offset
27  *offset_ptr += sizeof(val);
28  }
29  return val;
30 }
31 
32 template <typename T>
33 static T *getUs(uint32_t *offset_ptr, T *dst, uint32_t count,
34  const DataExtractor *de, bool isLittleEndian, const char *Data){
35  uint32_t offset = *offset_ptr;
36 
37  if (count > 0 && de->isValidOffsetForDataOfSize(offset, sizeof(*dst)*count)) {
38  for (T *value_ptr = dst, *end = dst + count; value_ptr != end;
39  ++value_ptr, offset += sizeof(*dst))
40  *value_ptr = getU<T>(offset_ptr, de, isLittleEndian, Data);
41  // Advance the offset
42  *offset_ptr = offset;
43  // Return a non-NULL pointer to the converted data as an indicator of
44  // success
45  return dst;
46  }
47  return nullptr;
48 }
49 
50 uint8_t DataExtractor::getU8(uint32_t *offset_ptr) const {
51  return getU<uint8_t>(offset_ptr, this, IsLittleEndian, Data.data());
52 }
53 
54 uint8_t *
55 DataExtractor::getU8(uint32_t *offset_ptr, uint8_t *dst, uint32_t count) const {
56  return getUs<uint8_t>(offset_ptr, dst, count, this, IsLittleEndian,
57  Data.data());
58 }
59 
60 
61 uint16_t DataExtractor::getU16(uint32_t *offset_ptr) const {
62  return getU<uint16_t>(offset_ptr, this, IsLittleEndian, Data.data());
63 }
64 
65 uint16_t *DataExtractor::getU16(uint32_t *offset_ptr, uint16_t *dst,
66  uint32_t count) const {
67  return getUs<uint16_t>(offset_ptr, dst, count, this, IsLittleEndian,
68  Data.data());
69 }
70 
72  uint24_t ExtractedVal =
73  getU<uint24_t>(offset_ptr, this, IsLittleEndian, Data.data());
74  // The 3 bytes are in the correct byte order for the host.
75  return ExtractedVal.getAsUint32(sys::IsLittleEndianHost);
76 }
77 
79  return getU<uint32_t>(offset_ptr, this, IsLittleEndian, Data.data());
80 }
81 
83  uint32_t count) const {
84  return getUs<uint32_t>(offset_ptr, dst, count, this, IsLittleEndian,
85  Data.data());
86 }
87 
88 uint64_t DataExtractor::getU64(uint32_t *offset_ptr) const {
89  return getU<uint64_t>(offset_ptr, this, IsLittleEndian, Data.data());
90 }
91 
92 uint64_t *DataExtractor::getU64(uint32_t *offset_ptr, uint64_t *dst,
93  uint32_t count) const {
94  return getUs<uint64_t>(offset_ptr, dst, count, this, IsLittleEndian,
95  Data.data());
96 }
97 
98 uint64_t
99 DataExtractor::getUnsigned(uint32_t *offset_ptr, uint32_t byte_size) const {
100  switch (byte_size) {
101  case 1:
102  return getU8(offset_ptr);
103  case 2:
104  return getU16(offset_ptr);
105  case 4:
106  return getU32(offset_ptr);
107  case 8:
108  return getU64(offset_ptr);
109  }
110  llvm_unreachable("getUnsigned unhandled case!");
111 }
112 
113 int64_t
114 DataExtractor::getSigned(uint32_t *offset_ptr, uint32_t byte_size) const {
115  switch (byte_size) {
116  case 1:
117  return (int8_t)getU8(offset_ptr);
118  case 2:
119  return (int16_t)getU16(offset_ptr);
120  case 4:
121  return (int32_t)getU32(offset_ptr);
122  case 8:
123  return (int64_t)getU64(offset_ptr);
124  }
125  llvm_unreachable("getSigned unhandled case!");
126 }
127 
128 const char *DataExtractor::getCStr(uint32_t *offset_ptr) const {
129  uint32_t offset = *offset_ptr;
130  StringRef::size_type pos = Data.find('\0', offset);
131  if (pos != StringRef::npos) {
132  *offset_ptr = pos + 1;
133  return Data.data() + offset;
134  }
135  return nullptr;
136 }
137 
139  uint32_t Start = *OffsetPtr;
140  StringRef::size_type Pos = Data.find('\0', Start);
141  if (Pos != StringRef::npos) {
142  *OffsetPtr = Pos + 1;
143  return StringRef(Data.data() + Start, Pos - Start);
144  }
145  return StringRef();
146 }
147 
148 uint64_t DataExtractor::getULEB128(uint32_t *offset_ptr) const {
149  assert(*offset_ptr <= Data.size());
150 
151  const char *error;
152  unsigned bytes_read;
153  uint64_t result = decodeULEB128(
154  reinterpret_cast<const uint8_t *>(Data.data() + *offset_ptr), &bytes_read,
155  reinterpret_cast<const uint8_t *>(Data.data() + Data.size()), &error);
156  if (error)
157  return 0;
158  *offset_ptr += bytes_read;
159  return result;
160 }
161 
162 int64_t DataExtractor::getSLEB128(uint32_t *offset_ptr) const {
163  assert(*offset_ptr <= Data.size());
164 
165  const char *error;
166  unsigned bytes_read;
167  int64_t result = decodeSLEB128(
168  reinterpret_cast<const uint8_t *>(Data.data() + *offset_ptr), &bytes_read,
169  reinterpret_cast<const uint8_t *>(Data.data() + Data.size()), &error);
170  if (error)
171  return 0;
172  *offset_ptr += bytes_read;
173  return result;
174 }
const_iterator end(StringRef path)
Get end iterator over path.
Definition: Path.cpp:233
void swapByteOrder(T &Value)
uint64_t getULEB128(uint32_t *offset_ptr) const
Extract a unsigned LEB128 value from *offset_ptr.
This class represents lattice values for constants.
Definition: AllocatorList.h:23
uint32_t getU24(uint32_t *offset_ptr) const
Extract a 24-bit unsigned value from *offset_ptr and return it in a uint32_t.
uint32_t getAsUint32(bool IsLittleEndian) const
Definition: DataExtractor.h:26
#define error(X)
uint16_t getU16(uint32_t *offset_ptr) const
Extract a uint16_t value from *offset_ptr.
uint32_t getU32(uint32_t *offset_ptr) const
Extract a uint32_t value from *offset_ptr.
An auxiliary type to facilitate extraction of 3-byte entities.
Definition: DataExtractor.h:18
int64_t decodeSLEB128(const uint8_t *p, unsigned *n=nullptr, const uint8_t *end=nullptr, const char **error=nullptr)
Utility function to decode a SLEB128 value.
Definition: LEB128.h:161
static const bool IsLittleEndianHost
Definition: Host.h:49
LLVM_NODISCARD size_t size() const
size - Get the string size.
Definition: StringRef.h:130
int64_t getSLEB128(uint32_t *offset_ptr) const
Extract a signed LEB128 value from *offset_ptr.
auto count(R &&Range, const E &Element) -> typename std::iterator_traits< decltype(adl_begin(Range))>::difference_type
Wrapper function around std::count to count the number of times an element Element occurs in the give...
Definition: STLExtras.h:1258
bool isValidOffsetForDataOfSize(uint32_t offset, uint32_t length) const
Test the availability of length bytes of data from offset.
static T * getUs(uint32_t *offset_ptr, T *dst, uint32_t count, const DataExtractor *de, bool isLittleEndian, const char *Data)
LLVM_NODISCARD size_t find(char C, size_t From=0) const
Search for the first character C in the string.
Definition: StringRef.h:285
int64_t getSigned(uint32_t *offset_ptr, uint32_t size) const
Extract an signed integer of size byte_size from *offset_ptr.
uint64_t decodeULEB128(const uint8_t *p, unsigned *n=nullptr, const uint8_t *end=nullptr, const char **error=nullptr)
Utility function to decode a ULEB128 value.
Definition: LEB128.h:128
uint8_t getU8(uint32_t *offset_ptr) const
Extract a uint8_t value from *offset_ptr.
uint64_t getU64(uint32_t *offset_ptr) const
Extract a uint64_t value from *offset_ptr.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
static const size_t npos
Definition: StringRef.h:50
uint64_t getUnsigned(uint32_t *offset_ptr, uint32_t byte_size) const
Extract an unsigned integer of size byte_size from *offset_ptr.
const char * getCStr(uint32_t *offset_ptr) const
Extract a C string from *offset_ptr.
LLVM_NODISCARD const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
Definition: StringRef.h:122
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
StringRef getCStrRef(uint32_t *OffsetPtr) const
Extract a C string from *OffsetPtr.
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:48
static T getU(uint32_t *offset_ptr, const DataExtractor *de, bool isLittleEndian, const char *Data)