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