1*7251ede7SZachary Turner //===- CodeViewRecordIO.cpp -------------------------------------*- C++ -*-===// 2*7251ede7SZachary Turner // 3*7251ede7SZachary Turner // The LLVM Compiler Infrastructure 4*7251ede7SZachary Turner // 5*7251ede7SZachary Turner // This file is distributed under the University of Illinois Open Source 6*7251ede7SZachary Turner // License. See LICENSE.TXT for details. 7*7251ede7SZachary Turner // 8*7251ede7SZachary Turner //===----------------------------------------------------------------------===// 9*7251ede7SZachary Turner 10*7251ede7SZachary Turner #include "llvm/DebugInfo/CodeView/CodeViewRecordIO.h" 11*7251ede7SZachary Turner #include "llvm/DebugInfo/CodeView/CodeView.h" 12*7251ede7SZachary Turner #include "llvm/DebugInfo/CodeView/RecordSerialization.h" 13*7251ede7SZachary Turner #include "llvm/DebugInfo/MSF/StreamReader.h" 14*7251ede7SZachary Turner #include "llvm/DebugInfo/MSF/StreamWriter.h" 15*7251ede7SZachary Turner 16*7251ede7SZachary Turner using namespace llvm; 17*7251ede7SZachary Turner using namespace llvm::codeview; 18*7251ede7SZachary Turner 19*7251ede7SZachary Turner Error CodeViewRecordIO::beginRecord(uint16_t Kind) { 20*7251ede7SZachary Turner assert(!CurrentRecord.hasValue() && "There is already a record active!"); 21*7251ede7SZachary Turner CurrentRecord.emplace(); 22*7251ede7SZachary Turner 23*7251ede7SZachary Turner CurrentRecord->Kind = Kind; 24*7251ede7SZachary Turner return Error::success(); 25*7251ede7SZachary Turner } 26*7251ede7SZachary Turner 27*7251ede7SZachary Turner Error CodeViewRecordIO::endRecord() { 28*7251ede7SZachary Turner assert(CurrentRecord.hasValue() && "Not in a record!"); 29*7251ede7SZachary Turner CurrentRecord.reset(); 30*7251ede7SZachary Turner return Error::success(); 31*7251ede7SZachary Turner } 32*7251ede7SZachary Turner 33*7251ede7SZachary Turner Error CodeViewRecordIO::skipPadding() { 34*7251ede7SZachary Turner assert(!isWriting() && "Cannot skip padding while writing!"); 35*7251ede7SZachary Turner 36*7251ede7SZachary Turner if (Reader->bytesRemaining() == 0) 37*7251ede7SZachary Turner return Error::success(); 38*7251ede7SZachary Turner 39*7251ede7SZachary Turner uint8_t Leaf = Reader->peek(); 40*7251ede7SZachary Turner if (Leaf < LF_PAD0) 41*7251ede7SZachary Turner return Error::success(); 42*7251ede7SZachary Turner // Leaf is greater than 0xf0. We should advance by the number of bytes in 43*7251ede7SZachary Turner // the low 4 bits. 44*7251ede7SZachary Turner unsigned BytesToAdvance = Leaf & 0x0F; 45*7251ede7SZachary Turner return Reader->skip(BytesToAdvance); 46*7251ede7SZachary Turner } 47*7251ede7SZachary Turner 48*7251ede7SZachary Turner Error CodeViewRecordIO::mapByteVectorTail(ArrayRef<uint8_t> &Bytes) { 49*7251ede7SZachary Turner if (isWriting()) { 50*7251ede7SZachary Turner if (auto EC = Writer->writeBytes(Bytes)) 51*7251ede7SZachary Turner return EC; 52*7251ede7SZachary Turner } else { 53*7251ede7SZachary Turner if (auto EC = Reader->readBytes(Bytes, Reader->bytesRemaining())) 54*7251ede7SZachary Turner return EC; 55*7251ede7SZachary Turner } 56*7251ede7SZachary Turner return Error::success(); 57*7251ede7SZachary Turner } 58*7251ede7SZachary Turner 59*7251ede7SZachary Turner Error CodeViewRecordIO::mapInteger(TypeIndex &TypeInd) { 60*7251ede7SZachary Turner if (isWriting()) { 61*7251ede7SZachary Turner if (auto EC = Writer->writeInteger(TypeInd.getIndex())) 62*7251ede7SZachary Turner return EC; 63*7251ede7SZachary Turner return Error::success(); 64*7251ede7SZachary Turner } 65*7251ede7SZachary Turner 66*7251ede7SZachary Turner uint32_t I; 67*7251ede7SZachary Turner if (auto EC = Reader->readInteger(I)) 68*7251ede7SZachary Turner return EC; 69*7251ede7SZachary Turner TypeInd.setIndex(I); 70*7251ede7SZachary Turner return Error::success(); 71*7251ede7SZachary Turner } 72*7251ede7SZachary Turner 73*7251ede7SZachary Turner Error CodeViewRecordIO::mapEncodedInteger(int64_t &Value) { 74*7251ede7SZachary Turner if (isWriting()) { 75*7251ede7SZachary Turner if (Value >= 0) { 76*7251ede7SZachary Turner if (auto EC = writeEncodedUnsignedInteger(static_cast<uint64_t>(Value))) 77*7251ede7SZachary Turner return EC; 78*7251ede7SZachary Turner } else { 79*7251ede7SZachary Turner if (auto EC = writeEncodedSignedInteger(Value)) 80*7251ede7SZachary Turner return EC; 81*7251ede7SZachary Turner } 82*7251ede7SZachary Turner } else { 83*7251ede7SZachary Turner APSInt N; 84*7251ede7SZachary Turner if (auto EC = consume(*Reader, N)) 85*7251ede7SZachary Turner return EC; 86*7251ede7SZachary Turner Value = N.getExtValue(); 87*7251ede7SZachary Turner } 88*7251ede7SZachary Turner 89*7251ede7SZachary Turner return Error::success(); 90*7251ede7SZachary Turner } 91*7251ede7SZachary Turner 92*7251ede7SZachary Turner Error CodeViewRecordIO::mapEncodedInteger(uint64_t &Value) { 93*7251ede7SZachary Turner if (isWriting()) { 94*7251ede7SZachary Turner if (auto EC = writeEncodedUnsignedInteger(Value)) 95*7251ede7SZachary Turner return EC; 96*7251ede7SZachary Turner } else { 97*7251ede7SZachary Turner APSInt N; 98*7251ede7SZachary Turner if (auto EC = consume(*Reader, N)) 99*7251ede7SZachary Turner return EC; 100*7251ede7SZachary Turner Value = N.getZExtValue(); 101*7251ede7SZachary Turner } 102*7251ede7SZachary Turner return Error::success(); 103*7251ede7SZachary Turner } 104*7251ede7SZachary Turner 105*7251ede7SZachary Turner Error CodeViewRecordIO::mapEncodedInteger(APSInt &Value) { 106*7251ede7SZachary Turner if (isWriting()) { 107*7251ede7SZachary Turner if (Value.isSigned()) 108*7251ede7SZachary Turner return writeEncodedSignedInteger(Value.getSExtValue()); 109*7251ede7SZachary Turner return writeEncodedUnsignedInteger(Value.getZExtValue()); 110*7251ede7SZachary Turner } 111*7251ede7SZachary Turner 112*7251ede7SZachary Turner return consume(*Reader, Value); 113*7251ede7SZachary Turner } 114*7251ede7SZachary Turner 115*7251ede7SZachary Turner Error CodeViewRecordIO::mapStringZ(StringRef &Value) { 116*7251ede7SZachary Turner if (isWriting()) { 117*7251ede7SZachary Turner if (auto EC = Writer->writeZeroString(Value)) 118*7251ede7SZachary Turner return EC; 119*7251ede7SZachary Turner } else { 120*7251ede7SZachary Turner if (auto EC = Reader->readZeroString(Value)) 121*7251ede7SZachary Turner return EC; 122*7251ede7SZachary Turner } 123*7251ede7SZachary Turner return Error::success(); 124*7251ede7SZachary Turner } 125*7251ede7SZachary Turner 126*7251ede7SZachary Turner Error CodeViewRecordIO::mapGuid(StringRef &Guid) { 127*7251ede7SZachary Turner if (isWriting()) { 128*7251ede7SZachary Turner assert(Guid.size() == 16 && "Invalid Guid Size!"); 129*7251ede7SZachary Turner if (auto EC = Writer->writeFixedString(Guid)) 130*7251ede7SZachary Turner return EC; 131*7251ede7SZachary Turner } else { 132*7251ede7SZachary Turner if (auto EC = Reader->readFixedString(Guid, 16)) 133*7251ede7SZachary Turner return EC; 134*7251ede7SZachary Turner } 135*7251ede7SZachary Turner return Error::success(); 136*7251ede7SZachary Turner } 137*7251ede7SZachary Turner 138*7251ede7SZachary Turner Error CodeViewRecordIO::writeEncodedSignedInteger(const int64_t &Value) { 139*7251ede7SZachary Turner assert(Value < 0 && "Encoded integer is not signed!"); 140*7251ede7SZachary Turner if (Value >= std::numeric_limits<int8_t>::min()) { 141*7251ede7SZachary Turner if (auto EC = Writer->writeInteger(static_cast<uint16_t>(LF_CHAR))) 142*7251ede7SZachary Turner return EC; 143*7251ede7SZachary Turner if (auto EC = Writer->writeInteger(static_cast<int8_t>(Value))) 144*7251ede7SZachary Turner return EC; 145*7251ede7SZachary Turner } else if (Value >= std::numeric_limits<int16_t>::min()) { 146*7251ede7SZachary Turner if (auto EC = Writer->writeInteger(static_cast<uint16_t>(LF_SHORT))) 147*7251ede7SZachary Turner return EC; 148*7251ede7SZachary Turner if (auto EC = Writer->writeInteger(static_cast<int16_t>(Value))) 149*7251ede7SZachary Turner return EC; 150*7251ede7SZachary Turner } else if (Value >= std::numeric_limits<int32_t>::min()) { 151*7251ede7SZachary Turner if (auto EC = Writer->writeInteger(static_cast<uint16_t>(LF_LONG))) 152*7251ede7SZachary Turner return EC; 153*7251ede7SZachary Turner if (auto EC = Writer->writeInteger(static_cast<int32_t>(Value))) 154*7251ede7SZachary Turner return EC; 155*7251ede7SZachary Turner } else { 156*7251ede7SZachary Turner if (auto EC = Writer->writeInteger(static_cast<uint16_t>(LF_QUADWORD))) 157*7251ede7SZachary Turner return EC; 158*7251ede7SZachary Turner if (auto EC = Writer->writeInteger(Value)) 159*7251ede7SZachary Turner return EC; 160*7251ede7SZachary Turner } 161*7251ede7SZachary Turner return Error::success(); 162*7251ede7SZachary Turner } 163*7251ede7SZachary Turner 164*7251ede7SZachary Turner Error CodeViewRecordIO::writeEncodedUnsignedInteger(const uint64_t &Value) { 165*7251ede7SZachary Turner if (Value < LF_NUMERIC) { 166*7251ede7SZachary Turner if (auto EC = Writer->writeInteger(static_cast<uint16_t>(Value))) 167*7251ede7SZachary Turner return EC; 168*7251ede7SZachary Turner } else if (Value <= std::numeric_limits<uint16_t>::max()) { 169*7251ede7SZachary Turner if (auto EC = Writer->writeInteger(static_cast<uint16_t>(LF_USHORT))) 170*7251ede7SZachary Turner return EC; 171*7251ede7SZachary Turner if (auto EC = Writer->writeInteger(static_cast<uint16_t>(Value))) 172*7251ede7SZachary Turner return EC; 173*7251ede7SZachary Turner } else if (Value <= std::numeric_limits<uint32_t>::max()) { 174*7251ede7SZachary Turner if (auto EC = Writer->writeInteger(static_cast<uint16_t>(LF_ULONG))) 175*7251ede7SZachary Turner return EC; 176*7251ede7SZachary Turner if (auto EC = Writer->writeInteger(static_cast<uint32_t>(Value))) 177*7251ede7SZachary Turner return EC; 178*7251ede7SZachary Turner } else { 179*7251ede7SZachary Turner if (auto EC = Writer->writeInteger(static_cast<uint16_t>(LF_UQUADWORD))) 180*7251ede7SZachary Turner return EC; 181*7251ede7SZachary Turner if (auto EC = Writer->writeInteger(Value)) 182*7251ede7SZachary Turner return EC; 183*7251ede7SZachary Turner } 184*7251ede7SZachary Turner 185*7251ede7SZachary Turner return Error::success(); 186*7251ede7SZachary Turner } 187