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/StreamReader.h" 14 #include "llvm/DebugInfo/MSF/StreamWriter.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::mapInteger(TypeIndex &TypeInd) { 79 if (isWriting()) { 80 if (auto EC = Writer->writeInteger(TypeInd.getIndex())) 81 return EC; 82 return Error::success(); 83 } 84 85 uint32_t I; 86 if (auto EC = Reader->readInteger(I)) 87 return EC; 88 TypeInd.setIndex(I); 89 return Error::success(); 90 } 91 92 Error CodeViewRecordIO::mapEncodedInteger(int64_t &Value) { 93 if (isWriting()) { 94 if (Value >= 0) { 95 if (auto EC = writeEncodedUnsignedInteger(static_cast<uint64_t>(Value))) 96 return EC; 97 } else { 98 if (auto EC = writeEncodedSignedInteger(Value)) 99 return EC; 100 } 101 } else { 102 APSInt N; 103 if (auto EC = consume(*Reader, N)) 104 return EC; 105 Value = N.getExtValue(); 106 } 107 108 return Error::success(); 109 } 110 111 Error CodeViewRecordIO::mapEncodedInteger(uint64_t &Value) { 112 if (isWriting()) { 113 if (auto EC = writeEncodedUnsignedInteger(Value)) 114 return EC; 115 } else { 116 APSInt N; 117 if (auto EC = consume(*Reader, N)) 118 return EC; 119 Value = N.getZExtValue(); 120 } 121 return Error::success(); 122 } 123 124 Error CodeViewRecordIO::mapEncodedInteger(APSInt &Value) { 125 if (isWriting()) { 126 if (Value.isSigned()) 127 return writeEncodedSignedInteger(Value.getSExtValue()); 128 return writeEncodedUnsignedInteger(Value.getZExtValue()); 129 } 130 131 return consume(*Reader, Value); 132 } 133 134 Error CodeViewRecordIO::mapStringZ(StringRef &Value) { 135 if (isWriting()) { 136 // Truncate if we attempt to write too much. 137 StringRef S = Value.take_front(maxFieldLength() - 1); 138 if (auto EC = Writer->writeZeroString(S)) 139 return EC; 140 } else { 141 if (auto EC = Reader->readZeroString(Value)) 142 return EC; 143 } 144 return Error::success(); 145 } 146 147 Error CodeViewRecordIO::mapGuid(StringRef &Guid) { 148 constexpr uint32_t GuidSize = 16; 149 if (maxFieldLength() < GuidSize) 150 return make_error<CodeViewError>(cv_error_code::insufficient_buffer); 151 152 if (isWriting()) { 153 assert(Guid.size() == 16 && "Invalid Guid Size!"); 154 if (auto EC = Writer->writeFixedString(Guid)) 155 return EC; 156 } else { 157 if (auto EC = Reader->readFixedString(Guid, 16)) 158 return EC; 159 } 160 return Error::success(); 161 } 162 163 Error CodeViewRecordIO::writeEncodedSignedInteger(const int64_t &Value) { 164 assert(Value < 0 && "Encoded integer is not signed!"); 165 if (Value >= std::numeric_limits<int8_t>::min()) { 166 if (auto EC = Writer->writeInteger(static_cast<uint16_t>(LF_CHAR))) 167 return EC; 168 if (auto EC = Writer->writeInteger(static_cast<int8_t>(Value))) 169 return EC; 170 } else if (Value >= std::numeric_limits<int16_t>::min()) { 171 if (auto EC = Writer->writeInteger(static_cast<uint16_t>(LF_SHORT))) 172 return EC; 173 if (auto EC = Writer->writeInteger(static_cast<int16_t>(Value))) 174 return EC; 175 } else if (Value >= std::numeric_limits<int32_t>::min()) { 176 if (auto EC = Writer->writeInteger(static_cast<uint16_t>(LF_LONG))) 177 return EC; 178 if (auto EC = Writer->writeInteger(static_cast<int32_t>(Value))) 179 return EC; 180 } else { 181 if (auto EC = Writer->writeInteger(static_cast<uint16_t>(LF_QUADWORD))) 182 return EC; 183 if (auto EC = Writer->writeInteger(Value)) 184 return EC; 185 } 186 return Error::success(); 187 } 188 189 Error CodeViewRecordIO::writeEncodedUnsignedInteger(const uint64_t &Value) { 190 if (Value < LF_NUMERIC) { 191 if (auto EC = Writer->writeInteger(static_cast<uint16_t>(Value))) 192 return EC; 193 } else if (Value <= std::numeric_limits<uint16_t>::max()) { 194 if (auto EC = Writer->writeInteger(static_cast<uint16_t>(LF_USHORT))) 195 return EC; 196 if (auto EC = Writer->writeInteger(static_cast<uint16_t>(Value))) 197 return EC; 198 } else if (Value <= std::numeric_limits<uint32_t>::max()) { 199 if (auto EC = Writer->writeInteger(static_cast<uint16_t>(LF_ULONG))) 200 return EC; 201 if (auto EC = Writer->writeInteger(static_cast<uint32_t>(Value))) 202 return EC; 203 } else { 204 if (auto EC = Writer->writeInteger(static_cast<uint16_t>(LF_UQUADWORD))) 205 return EC; 206 if (auto EC = Writer->writeInteger(Value)) 207 return EC; 208 } 209 210 return Error::success(); 211 } 212