xref: /llvm-project/llvm/lib/DebugInfo/CodeView/CodeViewRecordIO.cpp (revision faed8516e4f69665f2cd3315a2633f7b6b492524)
1 //===- CodeViewRecordIO.cpp -------------------------------------*- 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 #include "llvm/DebugInfo/CodeView/CodeViewRecordIO.h"
10 #include "llvm/DebugInfo/CodeView/CodeView.h"
11 #include "llvm/DebugInfo/CodeView/RecordSerialization.h"
12 #include "llvm/Support/BinaryStreamReader.h"
13 #include "llvm/Support/BinaryStreamWriter.h"
14 
15 using namespace llvm;
16 using namespace llvm::codeview;
17 
18 Error CodeViewRecordIO::beginRecord(Optional<uint32_t> MaxLength) {
19   RecordLimit Limit;
20   Limit.MaxLength = MaxLength;
21   Limit.BeginOffset = getCurrentOffset();
22   Limits.push_back(Limit);
23   resetStreamedLen();
24   return Error::success();
25 }
26 
27 Error CodeViewRecordIO::endRecord() {
28   assert(!Limits.empty() && "Not in a record!");
29   Limits.pop_back();
30   // We would like to assert that we actually read / wrote all the bytes that we
31   // expected to for this record, but unfortunately we can't do this.  Some
32   // producers such as MASM over-allocate for certain types of records and
33   // commit the extraneous data, so when reading we can't be sure every byte
34   // will have been read.  And when writing we over-allocate temporarily since
35   // we don't know how big the record is until we're finished writing it, so
36   // even though we don't commit the extraneous data, we still can't guarantee
37   // we're at the end of the allocated data.
38 
39   if (isStreaming()) {
40     // For streaming mode, add padding to align with 4 byte boundaries for each
41     // record
42     uint32_t Align = getStreamedLen() % 4;
43     if (Align == 0)
44       return Error::success();
45 
46     int PaddingBytes = 4 - Align;
47     while (PaddingBytes > 0) {
48       char Pad = static_cast<uint8_t>(LF_PAD0 + PaddingBytes);
49       StringRef BytesSR = StringRef(&Pad, sizeof(Pad));
50       Streamer->EmitBytes(BytesSR);
51       --PaddingBytes;
52     }
53   }
54   return Error::success();
55 }
56 
57 uint32_t CodeViewRecordIO::maxFieldLength() const {
58   if (isStreaming())
59     return 0;
60 
61   assert(!Limits.empty() && "Not in a record!");
62 
63   // The max length of the next field is the minimum of all lengths that would
64   // be allowed by any of the sub-records we're in.  In practice, we can only
65   // ever be at most 1 sub-record deep (in a FieldList), but this works for
66   // the general case.
67   uint32_t Offset = getCurrentOffset();
68   Optional<uint32_t> Min = Limits.front().bytesRemaining(Offset);
69   for (auto X : makeArrayRef(Limits).drop_front()) {
70     Optional<uint32_t> ThisMin = X.bytesRemaining(Offset);
71     if (ThisMin.hasValue())
72       Min = (Min.hasValue()) ? std::min(*Min, *ThisMin) : *ThisMin;
73   }
74   assert(Min.hasValue() && "Every field must have a maximum length!");
75 
76   return *Min;
77 }
78 
79 Error CodeViewRecordIO::padToAlignment(uint32_t Align) {
80   if (isReading())
81     return Reader->padToAlignment(Align);
82   return Writer->padToAlignment(Align);
83 }
84 
85 Error CodeViewRecordIO::skipPadding() {
86   assert(!isWriting() && "Cannot skip padding while writing!");
87 
88   if (Reader->bytesRemaining() == 0)
89     return Error::success();
90 
91   uint8_t Leaf = Reader->peek();
92   if (Leaf < LF_PAD0)
93     return Error::success();
94   // Leaf is greater than 0xf0. We should advance by the number of bytes in
95   // the low 4 bits.
96   unsigned BytesToAdvance = Leaf & 0x0F;
97   return Reader->skip(BytesToAdvance);
98 }
99 
100 Error CodeViewRecordIO::mapByteVectorTail(ArrayRef<uint8_t> &Bytes) {
101   if (isStreaming()) {
102     Streamer->EmitBinaryData(toStringRef(Bytes));
103     incrStreamedLen(Bytes.size());
104   } else if (isWriting()) {
105     if (auto EC = Writer->writeBytes(Bytes))
106       return EC;
107   } else {
108     if (auto EC = Reader->readBytes(Bytes, Reader->bytesRemaining()))
109       return EC;
110   }
111   return Error::success();
112 }
113 
114 Error CodeViewRecordIO::mapByteVectorTail(std::vector<uint8_t> &Bytes) {
115   ArrayRef<uint8_t> BytesRef(Bytes);
116   if (auto EC = mapByteVectorTail(BytesRef))
117     return EC;
118   if (!isWriting())
119     Bytes.assign(BytesRef.begin(), BytesRef.end());
120 
121   return Error::success();
122 }
123 
124 Error CodeViewRecordIO::mapInteger(TypeIndex &TypeInd) {
125   if (isStreaming()) {
126     Streamer->EmitIntValue(TypeInd.getIndex(), sizeof(TypeInd.getIndex()));
127     incrStreamedLen(sizeof(TypeInd.getIndex()));
128   } else if (isWriting()) {
129     if (auto EC = Writer->writeInteger(TypeInd.getIndex()))
130       return EC;
131   } else {
132     uint32_t I;
133     if (auto EC = Reader->readInteger(I))
134       return EC;
135     TypeInd.setIndex(I);
136   }
137   return Error::success();
138 }
139 
140 Error CodeViewRecordIO::mapEncodedInteger(int64_t &Value) {
141   if (isStreaming()) {
142     if (Value >= 0)
143       emitEncodedUnsignedInteger(static_cast<uint64_t>(Value));
144     else
145       emitEncodedSignedInteger(Value);
146   } else if (isWriting()) {
147     if (Value >= 0) {
148       if (auto EC = writeEncodedUnsignedInteger(static_cast<uint64_t>(Value)))
149         return EC;
150     } else {
151       if (auto EC = writeEncodedSignedInteger(Value))
152         return EC;
153     }
154   } else {
155     APSInt N;
156     if (auto EC = consume(*Reader, N))
157       return EC;
158     Value = N.getExtValue();
159   }
160 
161   return Error::success();
162 }
163 
164 Error CodeViewRecordIO::mapEncodedInteger(uint64_t &Value) {
165   if (isStreaming())
166     emitEncodedUnsignedInteger(Value);
167   else if (isWriting()) {
168     if (auto EC = writeEncodedUnsignedInteger(Value))
169       return EC;
170   } else {
171     APSInt N;
172     if (auto EC = consume(*Reader, N))
173       return EC;
174     Value = N.getZExtValue();
175   }
176   return Error::success();
177 }
178 
179 Error CodeViewRecordIO::mapEncodedInteger(APSInt &Value) {
180   if (isStreaming()) {
181     if (Value.isSigned())
182       emitEncodedSignedInteger(Value.getSExtValue());
183     else
184       emitEncodedUnsignedInteger(Value.getZExtValue());
185   } else if (isWriting()) {
186     if (Value.isSigned())
187       return writeEncodedSignedInteger(Value.getSExtValue());
188     return writeEncodedUnsignedInteger(Value.getZExtValue());
189   } else
190     return consume(*Reader, Value);
191   return Error::success();
192 }
193 
194 Error CodeViewRecordIO::mapStringZ(StringRef &Value) {
195   if (isStreaming()) {
196     auto NullTerminatedString = StringRef(Value.data(), Value.size() + 1);
197     Streamer->EmitBytes(NullTerminatedString);
198     incrStreamedLen(NullTerminatedString.size());
199   } else if (isWriting()) {
200     // Truncate if we attempt to write too much.
201     StringRef S = Value.take_front(maxFieldLength() - 1);
202     if (auto EC = Writer->writeCString(S))
203       return EC;
204   } else {
205     if (auto EC = Reader->readCString(Value))
206       return EC;
207   }
208   return Error::success();
209 }
210 
211 Error CodeViewRecordIO::mapGuid(GUID &Guid) {
212   constexpr uint32_t GuidSize = 16;
213 
214   if (isStreaming()) {
215     StringRef GuidSR =
216         StringRef((reinterpret_cast<const char *>(&Guid)), GuidSize);
217     Streamer->EmitBytes(GuidSR);
218     incrStreamedLen(GuidSize);
219     return Error::success();
220   }
221 
222   if (maxFieldLength() < GuidSize)
223     return make_error<CodeViewError>(cv_error_code::insufficient_buffer);
224 
225   if (isWriting()) {
226     if (auto EC = Writer->writeBytes(Guid.Guid))
227       return EC;
228   } else {
229     ArrayRef<uint8_t> GuidBytes;
230     if (auto EC = Reader->readBytes(GuidBytes, GuidSize))
231       return EC;
232     memcpy(Guid.Guid, GuidBytes.data(), GuidSize);
233   }
234   return Error::success();
235 }
236 
237 Error CodeViewRecordIO::mapStringZVectorZ(std::vector<StringRef> &Value) {
238 
239   if (!isReading()) {
240     for (auto V : Value) {
241       if (auto EC = mapStringZ(V))
242         return EC;
243     }
244     uint8_t FinalZero = 0;
245     if (auto EC = mapInteger(FinalZero))
246       return EC;
247   } else {
248     StringRef S;
249     if (auto EC = mapStringZ(S))
250       return EC;
251     while (!S.empty()) {
252       Value.push_back(S);
253       if (auto EC = mapStringZ(S))
254         return EC;
255     };
256   }
257   return Error::success();
258 }
259 
260 void CodeViewRecordIO::emitEncodedSignedInteger(const int64_t &Value) {
261   assert(Value < 0 && "Encoded integer is not signed!");
262   if (Value >= std::numeric_limits<int8_t>::min()) {
263     Streamer->EmitIntValue(LF_CHAR, 2);
264     Streamer->EmitIntValue(Value, 1);
265     incrStreamedLen(3);
266   } else if (Value >= std::numeric_limits<int16_t>::min()) {
267     Streamer->EmitIntValue(LF_SHORT, 2);
268     Streamer->EmitIntValue(Value, 2);
269     incrStreamedLen(4);
270   } else if (Value >= std::numeric_limits<int32_t>::min()) {
271     Streamer->EmitIntValue(LF_LONG, 2);
272     Streamer->EmitIntValue(Value, 4);
273     incrStreamedLen(6);
274   } else {
275     Streamer->EmitIntValue(LF_QUADWORD, 2);
276     Streamer->EmitIntValue(Value, 4);
277     incrStreamedLen(6);
278   }
279 }
280 
281 void CodeViewRecordIO::emitEncodedUnsignedInteger(const uint64_t &Value) {
282   if (Value < LF_NUMERIC) {
283     Streamer->EmitIntValue(Value, 2);
284     incrStreamedLen(2);
285   } else if (Value <= std::numeric_limits<uint16_t>::max()) {
286     Streamer->EmitIntValue(LF_USHORT, 2);
287     Streamer->EmitIntValue(Value, 2);
288     incrStreamedLen(4);
289   } else if (Value <= std::numeric_limits<uint32_t>::max()) {
290     Streamer->EmitIntValue(LF_ULONG, 2);
291     Streamer->EmitIntValue(Value, 4);
292     incrStreamedLen(6);
293   } else {
294     Streamer->EmitIntValue(LF_UQUADWORD, 2);
295     Streamer->EmitIntValue(Value, 8);
296     incrStreamedLen(6);
297   }
298 }
299 
300 Error CodeViewRecordIO::writeEncodedSignedInteger(const int64_t &Value) {
301   assert(Value < 0 && "Encoded integer is not signed!");
302   if (Value >= std::numeric_limits<int8_t>::min()) {
303     if (auto EC = Writer->writeInteger<uint16_t>(LF_CHAR))
304       return EC;
305     if (auto EC = Writer->writeInteger<int8_t>(Value))
306       return EC;
307   } else if (Value >= std::numeric_limits<int16_t>::min()) {
308     if (auto EC = Writer->writeInteger<uint16_t>(LF_SHORT))
309       return EC;
310     if (auto EC = Writer->writeInteger<int16_t>(Value))
311       return EC;
312   } else if (Value >= std::numeric_limits<int32_t>::min()) {
313     if (auto EC = Writer->writeInteger<uint16_t>(LF_LONG))
314       return EC;
315     if (auto EC = Writer->writeInteger<int32_t>(Value))
316       return EC;
317   } else {
318     if (auto EC = Writer->writeInteger<uint16_t>(LF_QUADWORD))
319       return EC;
320     if (auto EC = Writer->writeInteger(Value))
321       return EC;
322   }
323   return Error::success();
324 }
325 
326 Error CodeViewRecordIO::writeEncodedUnsignedInteger(const uint64_t &Value) {
327   if (Value < LF_NUMERIC) {
328     if (auto EC = Writer->writeInteger<uint16_t>(Value))
329       return EC;
330   } else if (Value <= std::numeric_limits<uint16_t>::max()) {
331     if (auto EC = Writer->writeInteger<uint16_t>(LF_USHORT))
332       return EC;
333     if (auto EC = Writer->writeInteger<uint16_t>(Value))
334       return EC;
335   } else if (Value <= std::numeric_limits<uint32_t>::max()) {
336     if (auto EC = Writer->writeInteger<uint16_t>(LF_ULONG))
337       return EC;
338     if (auto EC = Writer->writeInteger<uint32_t>(Value))
339       return EC;
340   } else {
341     if (auto EC = Writer->writeInteger<uint16_t>(LF_UQUADWORD))
342       return EC;
343     if (auto EC = Writer->writeInteger(Value))
344       return EC;
345   }
346 
347   return Error::success();
348 }
349