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