LLVM  4.0.0
CodeViewRecordIO.cpp
Go to the documentation of this file.
1 //===- CodeViewRecordIO.cpp -------------------------------------*- 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 
15 
16 using namespace llvm;
17 using namespace llvm::codeview;
18 
20  RecordLimit Limit;
21  Limit.MaxLength = MaxLength;
22  Limit.BeginOffset = getCurrentOffset();
23  Limits.push_back(Limit);
24  return Error::success();
25 }
26 
28  assert(!Limits.empty() && "Not in a record!");
29  Limits.pop_back();
30  return Error::success();
31 }
32 
34  assert(!Limits.empty() && "Not in a record!");
35 
36  // The max length of the next field is the minimum of all lengths that would
37  // be allowed by any of the sub-records we're in. In practice, we can only
38  // ever be at most 1 sub-record deep (in a FieldList), but this works for
39  // the general case.
40  uint32_t Offset = getCurrentOffset();
41  Optional<uint32_t> Min = Limits.front().bytesRemaining(Offset);
42  for (auto X : makeArrayRef(Limits).drop_front()) {
43  Optional<uint32_t> ThisMin = X.bytesRemaining(Offset);
44  if (ThisMin.hasValue())
45  Min = (Min.hasValue()) ? std::min(*Min, *ThisMin) : *ThisMin;
46  }
47  assert(Min.hasValue() && "Every field must have a maximum length!");
48 
49  return *Min;
50 }
51 
53  assert(!isWriting() && "Cannot skip padding while writing!");
54 
55  if (Reader->bytesRemaining() == 0)
56  return Error::success();
57 
58  uint8_t Leaf = Reader->peek();
59  if (Leaf < LF_PAD0)
60  return Error::success();
61  // Leaf is greater than 0xf0. We should advance by the number of bytes in
62  // the low 4 bits.
63  unsigned BytesToAdvance = Leaf & 0x0F;
64  return Reader->skip(BytesToAdvance);
65 }
66 
68  if (isWriting()) {
69  if (auto EC = Writer->writeBytes(Bytes))
70  return EC;
71  } else {
72  if (auto EC = Reader->readBytes(Bytes, Reader->bytesRemaining()))
73  return EC;
74  }
75  return Error::success();
76 }
77 
78 Error CodeViewRecordIO::mapByteVectorTail(std::vector<uint8_t> &Bytes) {
79  ArrayRef<uint8_t> BytesRef(Bytes);
80  if (auto EC = mapByteVectorTail(BytesRef))
81  return EC;
82  if (!isWriting())
83  Bytes.assign(BytesRef.begin(), BytesRef.end());
84 
85  return Error::success();
86 }
87 
89  if (isWriting()) {
90  if (auto EC = Writer->writeInteger(TypeInd.getIndex()))
91  return EC;
92  return Error::success();
93  }
94 
95  uint32_t I;
96  if (auto EC = Reader->readInteger(I))
97  return EC;
98  TypeInd.setIndex(I);
99  return Error::success();
100 }
101 
103  if (isWriting()) {
104  if (Value >= 0) {
105  if (auto EC = writeEncodedUnsignedInteger(static_cast<uint64_t>(Value)))
106  return EC;
107  } else {
108  if (auto EC = writeEncodedSignedInteger(Value))
109  return EC;
110  }
111  } else {
112  APSInt N;
113  if (auto EC = consume(*Reader, N))
114  return EC;
115  Value = N.getExtValue();
116  }
117 
118  return Error::success();
119 }
120 
122  if (isWriting()) {
123  if (auto EC = writeEncodedUnsignedInteger(Value))
124  return EC;
125  } else {
126  APSInt N;
127  if (auto EC = consume(*Reader, N))
128  return EC;
129  Value = N.getZExtValue();
130  }
131  return Error::success();
132 }
133 
135  if (isWriting()) {
136  if (Value.isSigned())
137  return writeEncodedSignedInteger(Value.getSExtValue());
138  return writeEncodedUnsignedInteger(Value.getZExtValue());
139  }
140 
141  return consume(*Reader, Value);
142 }
143 
145  if (isWriting()) {
146  // Truncate if we attempt to write too much.
147  StringRef S = Value.take_front(maxFieldLength() - 1);
148  if (auto EC = Writer->writeZeroString(S))
149  return EC;
150  } else {
151  if (auto EC = Reader->readZeroString(Value))
152  return EC;
153  }
154  return Error::success();
155 }
156 
158  constexpr uint32_t GuidSize = 16;
159  if (maxFieldLength() < GuidSize)
160  return make_error<CodeViewError>(cv_error_code::insufficient_buffer);
161 
162  if (isWriting()) {
163  assert(Guid.size() == 16 && "Invalid Guid Size!");
164  if (auto EC = Writer->writeFixedString(Guid))
165  return EC;
166  } else {
167  if (auto EC = Reader->readFixedString(Guid, 16))
168  return EC;
169  }
170  return Error::success();
171 }
172 
174  if (isWriting()) {
175  for (auto V : Value) {
176  if (auto EC = mapStringZ(V))
177  return EC;
178  }
179  if (auto EC = Writer->writeInteger(uint8_t(0)))
180  return EC;
181  } else {
182  StringRef S;
183  if (auto EC = mapStringZ(S))
184  return EC;
185  while (!S.empty()) {
186  Value.push_back(S);
187  if (auto EC = mapStringZ(S))
188  return EC;
189  };
190  }
191  return Error::success();
192 }
193 
194 Error CodeViewRecordIO::writeEncodedSignedInteger(const int64_t &Value) {
195  assert(Value < 0 && "Encoded integer is not signed!");
196  if (Value >= std::numeric_limits<int8_t>::min()) {
197  if (auto EC = Writer->writeInteger(static_cast<uint16_t>(LF_CHAR)))
198  return EC;
199  if (auto EC = Writer->writeInteger(static_cast<int8_t>(Value)))
200  return EC;
201  } else if (Value >= std::numeric_limits<int16_t>::min()) {
202  if (auto EC = Writer->writeInteger(static_cast<uint16_t>(LF_SHORT)))
203  return EC;
204  if (auto EC = Writer->writeInteger(static_cast<int16_t>(Value)))
205  return EC;
206  } else if (Value >= std::numeric_limits<int32_t>::min()) {
207  if (auto EC = Writer->writeInteger(static_cast<uint16_t>(LF_LONG)))
208  return EC;
209  if (auto EC = Writer->writeInteger(static_cast<int32_t>(Value)))
210  return EC;
211  } else {
212  if (auto EC = Writer->writeInteger(static_cast<uint16_t>(LF_QUADWORD)))
213  return EC;
214  if (auto EC = Writer->writeInteger(Value))
215  return EC;
216  }
217  return Error::success();
218 }
219 
220 Error CodeViewRecordIO::writeEncodedUnsignedInteger(const uint64_t &Value) {
221  if (Value < LF_NUMERIC) {
222  if (auto EC = Writer->writeInteger(static_cast<uint16_t>(Value)))
223  return EC;
224  } else if (Value <= std::numeric_limits<uint16_t>::max()) {
225  if (auto EC = Writer->writeInteger(static_cast<uint16_t>(LF_USHORT)))
226  return EC;
227  if (auto EC = Writer->writeInteger(static_cast<uint16_t>(Value)))
228  return EC;
229  } else if (Value <= std::numeric_limits<uint32_t>::max()) {
230  if (auto EC = Writer->writeInteger(static_cast<uint16_t>(LF_ULONG)))
231  return EC;
232  if (auto EC = Writer->writeInteger(static_cast<uint32_t>(Value)))
233  return EC;
234  } else {
235  if (auto EC = Writer->writeInteger(static_cast<uint16_t>(LF_UQUADWORD)))
236  return EC;
237  if (auto EC = Writer->writeInteger(Value))
238  return EC;
239  }
240 
241  return Error::success();
242 }
Error mapByteVectorTail(ArrayRef< uint8_t > &Bytes)
void push_back(const T &Elt)
Definition: SmallVector.h:211
Error readFixedString(StringRef &Dest, uint32_t Length)
Error writeZeroString(StringRef Str)
uint64_t getZExtValue() const
Get zero extended value.
Definition: APInt.h:1309
bool hasValue() const
Definition: Optional.h:125
Error consume(msf::StreamReader &Reader)
Error mapInteger(TypeIndex &TypeInd)
iterator end() const
Definition: ArrayRef.h:130
Error mapStringZVectorZ(std::vector< StringRef > &Value)
bool isSigned() const
Definition: APSInt.h:59
Error writeFixedString(StringRef Str)
int64_t getExtValue() const
Get the correctly-extended int64_t value.
Definition: APSInt.h:76
void setIndex(uint32_t I)
Definition: TypeIndex.h:104
ArrayRef< T > makeArrayRef(const T &OneElt)
Construct an ArrayRef from a single element.
Definition: ArrayRef.h:440
Error readZeroString(StringRef &Dest)
Error beginRecord(Optional< uint32_t > MaxLength)
LLVM_NODISCARD bool empty() const
Definition: SmallVector.h:60
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE StringRef take_front(size_t N=1) const
Return a StringRef equal to 'this' but with only the first N elements remaining.
Definition: StringRef.h:597
A 32-bit type reference.
Definition: TypeIndex.h:89
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE size_t size() const
size - Get the string size.
Definition: StringRef.h:135
Maximum length of the test input libFuzzer tries to guess a good value based on the corpus and reports it always prefer smaller inputs during the corpus shuffle When libFuzzer itself reports a bug this exit code will be used If indicates the maximal total time in seconds to run the fuzzer minimizes the provided crash input Use with etc Experimental Use value profile to guide fuzzing Number of simultaneous worker processes to run the jobs If min(jobs, NumberOfCpuCores()/2)\" is used.") FUZZER_FLAG_INT(reload
Error writeBytes(ArrayRef< uint8_t > Buffer)
uint32_t getIndex() const
Definition: TypeIndex.h:103
Error readBytes(ArrayRef< uint8_t > &Buffer, uint32_t Size)
int64_t getSExtValue() const
Get sign extended value.
Definition: APInt.h:1321
Error readInteger(uint8_t &Dest)
Error skip(uint32_t Amount)
uint32_t Offset
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang","erlang-compatible garbage collector")
iterator begin() const
Definition: ArrayRef.h:129
Error writeInteger(uint8_t Int)
static ErrorSuccess success()
Create a success value.
Error mapEncodedInteger(int64_t &Value)
uint8_t peek() const
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:130
#define I(x, y, z)
Definition: MD5.cpp:54
#define N
Error mapStringZ(StringRef &Value)
uint32_t bytesRemaining() const
Definition: StreamReader.h:108
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
LLVM Value Representation.
Definition: Value.h:71
Lightweight error class with error context and mandatory checking.
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:47