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