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 return Error::success(); 24 } 25 26 Error CodeViewRecordIO::endRecord() { 27 assert(!Limits.empty() && "Not in a record!"); 28 Limits.pop_back(); 29 // We would like to assert that we actually read / wrote all the bytes that we 30 // expected to for this record, but unfortunately we can't do this. Some 31 // producers such as MASM over-allocate for certain types of records and 32 // commit the extraneous data, so when reading we can't be sure every byte 33 // will have been read. And when writing we over-allocate temporarily since 34 // we don't know how big the record is until we're finished writing it, so 35 // even though we don't commit the extraneous data, we still can't guarantee 36 // we're at the end of the allocated data. 37 return Error::success(); 38 } 39 40 uint32_t CodeViewRecordIO::maxFieldLength() const { 41 assert(!Limits.empty() && "Not in a record!"); 42 43 // The max length of the next field is the minimum of all lengths that would 44 // be allowed by any of the sub-records we're in. In practice, we can only 45 // ever be at most 1 sub-record deep (in a FieldList), but this works for 46 // the general case. 47 uint32_t Offset = getCurrentOffset(); 48 Optional<uint32_t> Min = Limits.front().bytesRemaining(Offset); 49 for (auto X : makeArrayRef(Limits).drop_front()) { 50 Optional<uint32_t> ThisMin = X.bytesRemaining(Offset); 51 if (ThisMin.hasValue()) 52 Min = (Min.hasValue()) ? std::min(*Min, *ThisMin) : *ThisMin; 53 } 54 assert(Min.hasValue() && "Every field must have a maximum length!"); 55 56 return *Min; 57 } 58 59 Error CodeViewRecordIO::padToAlignment(uint32_t Align) { 60 if (isReading()) 61 return Reader->padToAlignment(Align); 62 return Writer->padToAlignment(Align); 63 } 64 65 Error CodeViewRecordIO::skipPadding() { 66 assert(!isWriting() && "Cannot skip padding while writing!"); 67 68 if (Reader->bytesRemaining() == 0) 69 return Error::success(); 70 71 uint8_t Leaf = Reader->peek(); 72 if (Leaf < LF_PAD0) 73 return Error::success(); 74 // Leaf is greater than 0xf0. We should advance by the number of bytes in 75 // the low 4 bits. 76 unsigned BytesToAdvance = Leaf & 0x0F; 77 return Reader->skip(BytesToAdvance); 78 } 79 80 Error CodeViewRecordIO::mapByteVectorTail(ArrayRef<uint8_t> &Bytes) { 81 if (isWriting()) { 82 if (auto EC = Writer->writeBytes(Bytes)) 83 return EC; 84 } else { 85 if (auto EC = Reader->readBytes(Bytes, Reader->bytesRemaining())) 86 return EC; 87 } 88 return Error::success(); 89 } 90 91 Error CodeViewRecordIO::mapByteVectorTail(std::vector<uint8_t> &Bytes) { 92 ArrayRef<uint8_t> BytesRef(Bytes); 93 if (auto EC = mapByteVectorTail(BytesRef)) 94 return EC; 95 if (!isWriting()) 96 Bytes.assign(BytesRef.begin(), BytesRef.end()); 97 98 return Error::success(); 99 } 100 101 Error CodeViewRecordIO::mapInteger(TypeIndex &TypeInd) { 102 if (isWriting()) { 103 if (auto EC = Writer->writeInteger(TypeInd.getIndex())) 104 return EC; 105 return Error::success(); 106 } 107 108 uint32_t I; 109 if (auto EC = Reader->readInteger(I)) 110 return EC; 111 TypeInd.setIndex(I); 112 return Error::success(); 113 } 114 115 Error CodeViewRecordIO::mapEncodedInteger(int64_t &Value) { 116 if (isWriting()) { 117 if (Value >= 0) { 118 if (auto EC = writeEncodedUnsignedInteger(static_cast<uint64_t>(Value))) 119 return EC; 120 } else { 121 if (auto EC = writeEncodedSignedInteger(Value)) 122 return EC; 123 } 124 } else { 125 APSInt N; 126 if (auto EC = consume(*Reader, N)) 127 return EC; 128 Value = N.getExtValue(); 129 } 130 131 return Error::success(); 132 } 133 134 Error CodeViewRecordIO::mapEncodedInteger(uint64_t &Value) { 135 if (isWriting()) { 136 if (auto EC = writeEncodedUnsignedInteger(Value)) 137 return EC; 138 } else { 139 APSInt N; 140 if (auto EC = consume(*Reader, N)) 141 return EC; 142 Value = N.getZExtValue(); 143 } 144 return Error::success(); 145 } 146 147 Error CodeViewRecordIO::mapEncodedInteger(APSInt &Value) { 148 if (isWriting()) { 149 if (Value.isSigned()) 150 return writeEncodedSignedInteger(Value.getSExtValue()); 151 return writeEncodedUnsignedInteger(Value.getZExtValue()); 152 } 153 154 return consume(*Reader, Value); 155 } 156 157 Error CodeViewRecordIO::mapStringZ(StringRef &Value) { 158 if (isWriting()) { 159 // Truncate if we attempt to write too much. 160 StringRef S = Value.take_front(maxFieldLength() - 1); 161 if (auto EC = Writer->writeCString(S)) 162 return EC; 163 } else { 164 if (auto EC = Reader->readCString(Value)) 165 return EC; 166 } 167 return Error::success(); 168 } 169 170 Error CodeViewRecordIO::mapGuid(GUID &Guid) { 171 constexpr uint32_t GuidSize = 16; 172 if (maxFieldLength() < GuidSize) 173 return make_error<CodeViewError>(cv_error_code::insufficient_buffer); 174 175 if (isWriting()) { 176 if (auto EC = Writer->writeBytes(Guid.Guid)) 177 return EC; 178 } else { 179 ArrayRef<uint8_t> GuidBytes; 180 if (auto EC = Reader->readBytes(GuidBytes, GuidSize)) 181 return EC; 182 memcpy(Guid.Guid, GuidBytes.data(), GuidSize); 183 } 184 return Error::success(); 185 } 186 187 Error CodeViewRecordIO::mapStringZVectorZ(std::vector<StringRef> &Value) { 188 if (isWriting()) { 189 for (auto V : Value) { 190 if (auto EC = mapStringZ(V)) 191 return EC; 192 } 193 if (auto EC = Writer->writeInteger<uint8_t>(0)) 194 return EC; 195 } else { 196 StringRef S; 197 if (auto EC = mapStringZ(S)) 198 return EC; 199 while (!S.empty()) { 200 Value.push_back(S); 201 if (auto EC = mapStringZ(S)) 202 return EC; 203 }; 204 } 205 return Error::success(); 206 } 207 208 Error CodeViewRecordIO::writeEncodedSignedInteger(const int64_t &Value) { 209 assert(Value < 0 && "Encoded integer is not signed!"); 210 if (Value >= std::numeric_limits<int8_t>::min()) { 211 if (auto EC = Writer->writeInteger<uint16_t>(LF_CHAR)) 212 return EC; 213 if (auto EC = Writer->writeInteger<int8_t>(Value)) 214 return EC; 215 } else if (Value >= std::numeric_limits<int16_t>::min()) { 216 if (auto EC = Writer->writeInteger<uint16_t>(LF_SHORT)) 217 return EC; 218 if (auto EC = Writer->writeInteger<int16_t>(Value)) 219 return EC; 220 } else if (Value >= std::numeric_limits<int32_t>::min()) { 221 if (auto EC = Writer->writeInteger<uint16_t>(LF_LONG)) 222 return EC; 223 if (auto EC = Writer->writeInteger<int32_t>(Value)) 224 return EC; 225 } else { 226 if (auto EC = Writer->writeInteger<uint16_t>(LF_QUADWORD)) 227 return EC; 228 if (auto EC = Writer->writeInteger(Value)) 229 return EC; 230 } 231 return Error::success(); 232 } 233 234 Error CodeViewRecordIO::writeEncodedUnsignedInteger(const uint64_t &Value) { 235 if (Value < LF_NUMERIC) { 236 if (auto EC = Writer->writeInteger<uint16_t>(Value)) 237 return EC; 238 } else if (Value <= std::numeric_limits<uint16_t>::max()) { 239 if (auto EC = Writer->writeInteger<uint16_t>(LF_USHORT)) 240 return EC; 241 if (auto EC = Writer->writeInteger<uint16_t>(Value)) 242 return EC; 243 } else if (Value <= std::numeric_limits<uint32_t>::max()) { 244 if (auto EC = Writer->writeInteger<uint16_t>(LF_ULONG)) 245 return EC; 246 if (auto EC = Writer->writeInteger<uint32_t>(Value)) 247 return EC; 248 } else { 249 if (auto EC = Writer->writeInteger<uint16_t>(LF_UQUADWORD)) 250 return EC; 251 if (auto EC = Writer->writeInteger(Value)) 252 return EC; 253 } 254 255 return Error::success(); 256 } 257