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 10 #include "llvm/DebugInfo/CodeView/CodeViewRecordIO.h" 11 #include "llvm/DebugInfo/CodeView/CodeView.h" 12 #include "llvm/DebugInfo/CodeView/RecordSerialization.h" 13 #include "llvm/DebugInfo/MSF/BinaryStreamReader.h" 14 #include "llvm/DebugInfo/MSF/BinaryStreamWriter.h" 15 16 using namespace llvm; 17 using namespace llvm::codeview; 18 19 Error CodeViewRecordIO::beginRecord(Optional<uint32_t> MaxLength) { 20 RecordLimit Limit; 21 Limit.MaxLength = MaxLength; 22 Limit.BeginOffset = getCurrentOffset(); 23 Limits.push_back(Limit); 24 return Error::success(); 25 } 26 27 Error CodeViewRecordIO::endRecord() { 28 assert(!Limits.empty() && "Not in a record!"); 29 Limits.pop_back(); 30 return Error::success(); 31 } 32 33 uint32_t CodeViewRecordIO::maxFieldLength() const { 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 52 Error CodeViewRecordIO::skipPadding() { 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 67 Error CodeViewRecordIO::mapByteVectorTail(ArrayRef<uint8_t> &Bytes) { 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 88 Error CodeViewRecordIO::mapInteger(TypeIndex &TypeInd) { 89 if (isWriting()) { 90 if (auto EC = 91 Writer->writeInteger(TypeInd.getIndex(), llvm::support::little)) 92 return EC; 93 return Error::success(); 94 } 95 96 uint32_t I; 97 if (auto EC = Reader->readInteger(I, llvm::support::little)) 98 return EC; 99 TypeInd.setIndex(I); 100 return Error::success(); 101 } 102 103 Error CodeViewRecordIO::mapEncodedInteger(int64_t &Value) { 104 if (isWriting()) { 105 if (Value >= 0) { 106 if (auto EC = writeEncodedUnsignedInteger(static_cast<uint64_t>(Value))) 107 return EC; 108 } else { 109 if (auto EC = writeEncodedSignedInteger(Value)) 110 return EC; 111 } 112 } else { 113 APSInt N; 114 if (auto EC = consume(*Reader, N)) 115 return EC; 116 Value = N.getExtValue(); 117 } 118 119 return Error::success(); 120 } 121 122 Error CodeViewRecordIO::mapEncodedInteger(uint64_t &Value) { 123 if (isWriting()) { 124 if (auto EC = writeEncodedUnsignedInteger(Value)) 125 return EC; 126 } else { 127 APSInt N; 128 if (auto EC = consume(*Reader, N)) 129 return EC; 130 Value = N.getZExtValue(); 131 } 132 return Error::success(); 133 } 134 135 Error CodeViewRecordIO::mapEncodedInteger(APSInt &Value) { 136 if (isWriting()) { 137 if (Value.isSigned()) 138 return writeEncodedSignedInteger(Value.getSExtValue()); 139 return writeEncodedUnsignedInteger(Value.getZExtValue()); 140 } 141 142 return consume(*Reader, Value); 143 } 144 145 Error CodeViewRecordIO::mapStringZ(StringRef &Value) { 146 if (isWriting()) { 147 // Truncate if we attempt to write too much. 148 StringRef S = Value.take_front(maxFieldLength() - 1); 149 if (auto EC = Writer->writeCString(S)) 150 return EC; 151 } else { 152 if (auto EC = Reader->readCString(Value)) 153 return EC; 154 } 155 return Error::success(); 156 } 157 158 Error CodeViewRecordIO::mapGuid(StringRef &Guid) { 159 constexpr uint32_t GuidSize = 16; 160 if (maxFieldLength() < GuidSize) 161 return make_error<CodeViewError>(cv_error_code::insufficient_buffer); 162 163 if (isWriting()) { 164 assert(Guid.size() == 16 && "Invalid Guid Size!"); 165 if (auto EC = Writer->writeFixedString(Guid)) 166 return EC; 167 } else { 168 if (auto EC = Reader->readFixedString(Guid, 16)) 169 return EC; 170 } 171 return Error::success(); 172 } 173 174 Error CodeViewRecordIO::mapStringZVectorZ(std::vector<StringRef> &Value) { 175 if (isWriting()) { 176 for (auto V : Value) { 177 if (auto EC = mapStringZ(V)) 178 return EC; 179 } 180 if (auto EC = Writer->writeInteger<uint8_t>(0, llvm::support::little)) 181 return EC; 182 } else { 183 StringRef S; 184 if (auto EC = mapStringZ(S)) 185 return EC; 186 while (!S.empty()) { 187 Value.push_back(S); 188 if (auto EC = mapStringZ(S)) 189 return EC; 190 }; 191 } 192 return Error::success(); 193 } 194 195 Error CodeViewRecordIO::writeEncodedSignedInteger(const int64_t &Value) { 196 assert(Value < 0 && "Encoded integer is not signed!"); 197 if (Value >= std::numeric_limits<int8_t>::min()) { 198 if (auto EC = 199 Writer->writeInteger<uint16_t>(LF_CHAR, llvm::support::little)) 200 return EC; 201 if (auto EC = Writer->writeInteger<int8_t>(Value, llvm::support::little)) 202 return EC; 203 } else if (Value >= std::numeric_limits<int16_t>::min()) { 204 if (auto EC = 205 Writer->writeInteger<uint16_t>(LF_SHORT, llvm::support::little)) 206 return EC; 207 if (auto EC = Writer->writeInteger<int16_t>(Value, llvm::support::little)) 208 return EC; 209 } else if (Value >= std::numeric_limits<int32_t>::min()) { 210 if (auto EC = 211 Writer->writeInteger<uint16_t>(LF_LONG, llvm::support::little)) 212 return EC; 213 if (auto EC = Writer->writeInteger<int32_t>(Value, llvm::support::little)) 214 return EC; 215 } else { 216 if (auto EC = 217 Writer->writeInteger<uint16_t>(LF_QUADWORD, llvm::support::little)) 218 return EC; 219 if (auto EC = Writer->writeInteger(Value, llvm::support::little)) 220 return EC; 221 } 222 return Error::success(); 223 } 224 225 Error CodeViewRecordIO::writeEncodedUnsignedInteger(const uint64_t &Value) { 226 if (Value < LF_NUMERIC) { 227 if (auto EC = Writer->writeInteger<uint16_t>(Value, llvm::support::little)) 228 return EC; 229 } else if (Value <= std::numeric_limits<uint16_t>::max()) { 230 if (auto EC = 231 Writer->writeInteger<uint16_t>(LF_USHORT, llvm::support::little)) 232 return EC; 233 if (auto EC = Writer->writeInteger<uint16_t>(Value, llvm::support::little)) 234 return EC; 235 } else if (Value <= std::numeric_limits<uint32_t>::max()) { 236 if (auto EC = 237 Writer->writeInteger<uint16_t>(LF_ULONG, llvm::support::little)) 238 return EC; 239 if (auto EC = Writer->writeInteger<uint32_t>(Value, llvm::support::little)) 240 return EC; 241 } else { 242 if (auto EC = 243 Writer->writeInteger<uint16_t>(LF_UQUADWORD, llvm::support::little)) 244 return EC; 245 if (auto EC = Writer->writeInteger(Value, llvm::support::little)) 246 return EC; 247 } 248 249 return Error::success(); 250 } 251