17251ede7SZachary Turner //===- CodeViewRecordIO.cpp -------------------------------------*- C++ -*-===// 27251ede7SZachary Turner // 37251ede7SZachary Turner // The LLVM Compiler Infrastructure 47251ede7SZachary Turner // 57251ede7SZachary Turner // This file is distributed under the University of Illinois Open Source 67251ede7SZachary Turner // License. See LICENSE.TXT for details. 77251ede7SZachary Turner // 87251ede7SZachary Turner //===----------------------------------------------------------------------===// 97251ede7SZachary Turner 107251ede7SZachary Turner #include "llvm/DebugInfo/CodeView/CodeViewRecordIO.h" 117251ede7SZachary Turner #include "llvm/DebugInfo/CodeView/CodeView.h" 127251ede7SZachary Turner #include "llvm/DebugInfo/CodeView/RecordSerialization.h" 137251ede7SZachary Turner #include "llvm/DebugInfo/MSF/StreamReader.h" 147251ede7SZachary Turner #include "llvm/DebugInfo/MSF/StreamWriter.h" 157251ede7SZachary Turner 167251ede7SZachary Turner using namespace llvm; 177251ede7SZachary Turner using namespace llvm::codeview; 187251ede7SZachary Turner 19*4efa0a42SZachary Turner Error CodeViewRecordIO::beginRecord(Optional<uint32_t> MaxLength) { 20*4efa0a42SZachary Turner RecordLimit Limit; 21*4efa0a42SZachary Turner Limit.MaxLength = MaxLength; 22*4efa0a42SZachary Turner Limit.BeginOffset = getCurrentOffset(); 23*4efa0a42SZachary Turner Limits.push_back(Limit); 247251ede7SZachary Turner return Error::success(); 257251ede7SZachary Turner } 267251ede7SZachary Turner 277251ede7SZachary Turner Error CodeViewRecordIO::endRecord() { 28*4efa0a42SZachary Turner assert(!Limits.empty() && "Not in a record!"); 29*4efa0a42SZachary Turner Limits.pop_back(); 307251ede7SZachary Turner return Error::success(); 317251ede7SZachary Turner } 327251ede7SZachary Turner 33*4efa0a42SZachary Turner uint32_t CodeViewRecordIO::maxFieldLength() const { 34*4efa0a42SZachary Turner assert(!Limits.empty() && "Not in a record!"); 35*4efa0a42SZachary Turner 36*4efa0a42SZachary Turner // The max length of the next field is the minimum of all lengths that would 37*4efa0a42SZachary Turner // be allowed by any of the sub-records we're in. In practice, we can only 38*4efa0a42SZachary Turner // ever be at most 1 sub-record deep (in a FieldList), but this works for 39*4efa0a42SZachary Turner // the general case. 40*4efa0a42SZachary Turner uint32_t Offset = getCurrentOffset(); 41*4efa0a42SZachary Turner Optional<uint32_t> Min = Limits.front().bytesRemaining(Offset); 42*4efa0a42SZachary Turner for (auto X : makeArrayRef(Limits).drop_front()) { 43*4efa0a42SZachary Turner Optional<uint32_t> ThisMin = X.bytesRemaining(Offset); 44*4efa0a42SZachary Turner if (ThisMin.hasValue()) 45*4efa0a42SZachary Turner Min = (Min.hasValue()) ? std::min(*Min, *ThisMin) : *ThisMin; 46*4efa0a42SZachary Turner } 47*4efa0a42SZachary Turner assert(Min.hasValue() && "Every field must have a maximum length!"); 48*4efa0a42SZachary Turner 49*4efa0a42SZachary Turner return *Min; 50*4efa0a42SZachary Turner } 51*4efa0a42SZachary Turner 527251ede7SZachary Turner Error CodeViewRecordIO::skipPadding() { 537251ede7SZachary Turner assert(!isWriting() && "Cannot skip padding while writing!"); 547251ede7SZachary Turner 557251ede7SZachary Turner if (Reader->bytesRemaining() == 0) 567251ede7SZachary Turner return Error::success(); 577251ede7SZachary Turner 587251ede7SZachary Turner uint8_t Leaf = Reader->peek(); 597251ede7SZachary Turner if (Leaf < LF_PAD0) 607251ede7SZachary Turner return Error::success(); 617251ede7SZachary Turner // Leaf is greater than 0xf0. We should advance by the number of bytes in 627251ede7SZachary Turner // the low 4 bits. 637251ede7SZachary Turner unsigned BytesToAdvance = Leaf & 0x0F; 647251ede7SZachary Turner return Reader->skip(BytesToAdvance); 657251ede7SZachary Turner } 667251ede7SZachary Turner 677251ede7SZachary Turner Error CodeViewRecordIO::mapByteVectorTail(ArrayRef<uint8_t> &Bytes) { 687251ede7SZachary Turner if (isWriting()) { 697251ede7SZachary Turner if (auto EC = Writer->writeBytes(Bytes)) 707251ede7SZachary Turner return EC; 717251ede7SZachary Turner } else { 727251ede7SZachary Turner if (auto EC = Reader->readBytes(Bytes, Reader->bytesRemaining())) 737251ede7SZachary Turner return EC; 747251ede7SZachary Turner } 757251ede7SZachary Turner return Error::success(); 767251ede7SZachary Turner } 777251ede7SZachary Turner 787251ede7SZachary Turner Error CodeViewRecordIO::mapInteger(TypeIndex &TypeInd) { 797251ede7SZachary Turner if (isWriting()) { 807251ede7SZachary Turner if (auto EC = Writer->writeInteger(TypeInd.getIndex())) 817251ede7SZachary Turner return EC; 827251ede7SZachary Turner return Error::success(); 837251ede7SZachary Turner } 847251ede7SZachary Turner 857251ede7SZachary Turner uint32_t I; 867251ede7SZachary Turner if (auto EC = Reader->readInteger(I)) 877251ede7SZachary Turner return EC; 887251ede7SZachary Turner TypeInd.setIndex(I); 897251ede7SZachary Turner return Error::success(); 907251ede7SZachary Turner } 917251ede7SZachary Turner 927251ede7SZachary Turner Error CodeViewRecordIO::mapEncodedInteger(int64_t &Value) { 937251ede7SZachary Turner if (isWriting()) { 947251ede7SZachary Turner if (Value >= 0) { 957251ede7SZachary Turner if (auto EC = writeEncodedUnsignedInteger(static_cast<uint64_t>(Value))) 967251ede7SZachary Turner return EC; 977251ede7SZachary Turner } else { 987251ede7SZachary Turner if (auto EC = writeEncodedSignedInteger(Value)) 997251ede7SZachary Turner return EC; 1007251ede7SZachary Turner } 1017251ede7SZachary Turner } else { 1027251ede7SZachary Turner APSInt N; 1037251ede7SZachary Turner if (auto EC = consume(*Reader, N)) 1047251ede7SZachary Turner return EC; 1057251ede7SZachary Turner Value = N.getExtValue(); 1067251ede7SZachary Turner } 1077251ede7SZachary Turner 1087251ede7SZachary Turner return Error::success(); 1097251ede7SZachary Turner } 1107251ede7SZachary Turner 1117251ede7SZachary Turner Error CodeViewRecordIO::mapEncodedInteger(uint64_t &Value) { 1127251ede7SZachary Turner if (isWriting()) { 1137251ede7SZachary Turner if (auto EC = writeEncodedUnsignedInteger(Value)) 1147251ede7SZachary Turner return EC; 1157251ede7SZachary Turner } else { 1167251ede7SZachary Turner APSInt N; 1177251ede7SZachary Turner if (auto EC = consume(*Reader, N)) 1187251ede7SZachary Turner return EC; 1197251ede7SZachary Turner Value = N.getZExtValue(); 1207251ede7SZachary Turner } 1217251ede7SZachary Turner return Error::success(); 1227251ede7SZachary Turner } 1237251ede7SZachary Turner 1247251ede7SZachary Turner Error CodeViewRecordIO::mapEncodedInteger(APSInt &Value) { 1257251ede7SZachary Turner if (isWriting()) { 1267251ede7SZachary Turner if (Value.isSigned()) 1277251ede7SZachary Turner return writeEncodedSignedInteger(Value.getSExtValue()); 1287251ede7SZachary Turner return writeEncodedUnsignedInteger(Value.getZExtValue()); 1297251ede7SZachary Turner } 1307251ede7SZachary Turner 1317251ede7SZachary Turner return consume(*Reader, Value); 1327251ede7SZachary Turner } 1337251ede7SZachary Turner 1347251ede7SZachary Turner Error CodeViewRecordIO::mapStringZ(StringRef &Value) { 1357251ede7SZachary Turner if (isWriting()) { 136*4efa0a42SZachary Turner // Truncate if we attempt to write too much. 137*4efa0a42SZachary Turner StringRef S = Value.take_front(maxFieldLength() - 1); 138*4efa0a42SZachary Turner if (auto EC = Writer->writeZeroString(S)) 1397251ede7SZachary Turner return EC; 1407251ede7SZachary Turner } else { 1417251ede7SZachary Turner if (auto EC = Reader->readZeroString(Value)) 1427251ede7SZachary Turner return EC; 1437251ede7SZachary Turner } 1447251ede7SZachary Turner return Error::success(); 1457251ede7SZachary Turner } 1467251ede7SZachary Turner 1477251ede7SZachary Turner Error CodeViewRecordIO::mapGuid(StringRef &Guid) { 148*4efa0a42SZachary Turner constexpr uint32_t GuidSize = 16; 149*4efa0a42SZachary Turner if (maxFieldLength() < GuidSize) 150*4efa0a42SZachary Turner return make_error<CodeViewError>(cv_error_code::insufficient_buffer); 151*4efa0a42SZachary Turner 1527251ede7SZachary Turner if (isWriting()) { 1537251ede7SZachary Turner assert(Guid.size() == 16 && "Invalid Guid Size!"); 1547251ede7SZachary Turner if (auto EC = Writer->writeFixedString(Guid)) 1557251ede7SZachary Turner return EC; 1567251ede7SZachary Turner } else { 1577251ede7SZachary Turner if (auto EC = Reader->readFixedString(Guid, 16)) 1587251ede7SZachary Turner return EC; 1597251ede7SZachary Turner } 1607251ede7SZachary Turner return Error::success(); 1617251ede7SZachary Turner } 1627251ede7SZachary Turner 1637251ede7SZachary Turner Error CodeViewRecordIO::writeEncodedSignedInteger(const int64_t &Value) { 1647251ede7SZachary Turner assert(Value < 0 && "Encoded integer is not signed!"); 1657251ede7SZachary Turner if (Value >= std::numeric_limits<int8_t>::min()) { 1667251ede7SZachary Turner if (auto EC = Writer->writeInteger(static_cast<uint16_t>(LF_CHAR))) 1677251ede7SZachary Turner return EC; 1687251ede7SZachary Turner if (auto EC = Writer->writeInteger(static_cast<int8_t>(Value))) 1697251ede7SZachary Turner return EC; 1707251ede7SZachary Turner } else if (Value >= std::numeric_limits<int16_t>::min()) { 1717251ede7SZachary Turner if (auto EC = Writer->writeInteger(static_cast<uint16_t>(LF_SHORT))) 1727251ede7SZachary Turner return EC; 1737251ede7SZachary Turner if (auto EC = Writer->writeInteger(static_cast<int16_t>(Value))) 1747251ede7SZachary Turner return EC; 1757251ede7SZachary Turner } else if (Value >= std::numeric_limits<int32_t>::min()) { 1767251ede7SZachary Turner if (auto EC = Writer->writeInteger(static_cast<uint16_t>(LF_LONG))) 1777251ede7SZachary Turner return EC; 1787251ede7SZachary Turner if (auto EC = Writer->writeInteger(static_cast<int32_t>(Value))) 1797251ede7SZachary Turner return EC; 1807251ede7SZachary Turner } else { 1817251ede7SZachary Turner if (auto EC = Writer->writeInteger(static_cast<uint16_t>(LF_QUADWORD))) 1827251ede7SZachary Turner return EC; 1837251ede7SZachary Turner if (auto EC = Writer->writeInteger(Value)) 1847251ede7SZachary Turner return EC; 1857251ede7SZachary Turner } 1867251ede7SZachary Turner return Error::success(); 1877251ede7SZachary Turner } 1887251ede7SZachary Turner 1897251ede7SZachary Turner Error CodeViewRecordIO::writeEncodedUnsignedInteger(const uint64_t &Value) { 1907251ede7SZachary Turner if (Value < LF_NUMERIC) { 1917251ede7SZachary Turner if (auto EC = Writer->writeInteger(static_cast<uint16_t>(Value))) 1927251ede7SZachary Turner return EC; 1937251ede7SZachary Turner } else if (Value <= std::numeric_limits<uint16_t>::max()) { 1947251ede7SZachary Turner if (auto EC = Writer->writeInteger(static_cast<uint16_t>(LF_USHORT))) 1957251ede7SZachary Turner return EC; 1967251ede7SZachary Turner if (auto EC = Writer->writeInteger(static_cast<uint16_t>(Value))) 1977251ede7SZachary Turner return EC; 1987251ede7SZachary Turner } else if (Value <= std::numeric_limits<uint32_t>::max()) { 1997251ede7SZachary Turner if (auto EC = Writer->writeInteger(static_cast<uint16_t>(LF_ULONG))) 2007251ede7SZachary Turner return EC; 2017251ede7SZachary Turner if (auto EC = Writer->writeInteger(static_cast<uint32_t>(Value))) 2027251ede7SZachary Turner return EC; 2037251ede7SZachary Turner } else { 2047251ede7SZachary Turner if (auto EC = Writer->writeInteger(static_cast<uint16_t>(LF_UQUADWORD))) 2057251ede7SZachary Turner return EC; 2067251ede7SZachary Turner if (auto EC = Writer->writeInteger(Value)) 2077251ede7SZachary Turner return EC; 2087251ede7SZachary Turner } 2097251ede7SZachary Turner 2107251ede7SZachary Turner return Error::success(); 2117251ede7SZachary Turner } 212