17251ede7SZachary Turner //===- CodeViewRecordIO.cpp -------------------------------------*- C++ -*-===// 27251ede7SZachary Turner // 32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information. 52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 67251ede7SZachary Turner // 77251ede7SZachary Turner //===----------------------------------------------------------------------===// 87251ede7SZachary Turner 97251ede7SZachary Turner #include "llvm/DebugInfo/CodeView/CodeViewRecordIO.h" 107251ede7SZachary Turner #include "llvm/DebugInfo/CodeView/CodeView.h" 117251ede7SZachary Turner #include "llvm/DebugInfo/CodeView/RecordSerialization.h" 12d9dc2829SZachary Turner #include "llvm/Support/BinaryStreamReader.h" 13d9dc2829SZachary Turner #include "llvm/Support/BinaryStreamWriter.h" 147251ede7SZachary Turner 157251ede7SZachary Turner using namespace llvm; 167251ede7SZachary Turner using namespace llvm::codeview; 177251ede7SZachary Turner 184efa0a42SZachary Turner Error CodeViewRecordIO::beginRecord(Optional<uint32_t> MaxLength) { 194efa0a42SZachary Turner RecordLimit Limit; 204efa0a42SZachary Turner Limit.MaxLength = MaxLength; 214efa0a42SZachary Turner Limit.BeginOffset = getCurrentOffset(); 224efa0a42SZachary Turner Limits.push_back(Limit); 237251ede7SZachary Turner return Error::success(); 247251ede7SZachary Turner } 257251ede7SZachary Turner 267251ede7SZachary Turner Error CodeViewRecordIO::endRecord() { 274efa0a42SZachary Turner assert(!Limits.empty() && "Not in a record!"); 284efa0a42SZachary Turner Limits.pop_back(); 29ebd3ae83SZachary Turner // We would like to assert that we actually read / wrote all the bytes that we 30ebd3ae83SZachary Turner // expected to for this record, but unfortunately we can't do this. Some 31ebd3ae83SZachary Turner // producers such as MASM over-allocate for certain types of records and 32ebd3ae83SZachary Turner // commit the extraneous data, so when reading we can't be sure every byte 33ebd3ae83SZachary Turner // will have been read. And when writing we over-allocate temporarily since 34ebd3ae83SZachary Turner // we don't know how big the record is until we're finished writing it, so 35ebd3ae83SZachary Turner // even though we don't commit the extraneous data, we still can't guarantee 36ebd3ae83SZachary Turner // we're at the end of the allocated data. 37faed8516SNilanjana Basu 38faed8516SNilanjana Basu if (isStreaming()) { 39faed8516SNilanjana Basu // For streaming mode, add padding to align with 4 byte boundaries for each 40faed8516SNilanjana Basu // record 41faed8516SNilanjana Basu uint32_t Align = getStreamedLen() % 4; 42faed8516SNilanjana Basu if (Align == 0) 43faed8516SNilanjana Basu return Error::success(); 44faed8516SNilanjana Basu 45faed8516SNilanjana Basu int PaddingBytes = 4 - Align; 46faed8516SNilanjana Basu while (PaddingBytes > 0) { 47faed8516SNilanjana Basu char Pad = static_cast<uint8_t>(LF_PAD0 + PaddingBytes); 48faed8516SNilanjana Basu StringRef BytesSR = StringRef(&Pad, sizeof(Pad)); 49a55daa14SFangrui Song Streamer->emitBytes(BytesSR); 50faed8516SNilanjana Basu --PaddingBytes; 51faed8516SNilanjana Basu } 5206b8fe8dSNilanjana Basu resetStreamedLen(); 53faed8516SNilanjana Basu } 547251ede7SZachary Turner return Error::success(); 557251ede7SZachary Turner } 567251ede7SZachary Turner 574efa0a42SZachary Turner uint32_t CodeViewRecordIO::maxFieldLength() const { 58faed8516SNilanjana Basu if (isStreaming()) 59faed8516SNilanjana Basu return 0; 60faed8516SNilanjana Basu 614efa0a42SZachary Turner assert(!Limits.empty() && "Not in a record!"); 624efa0a42SZachary Turner 634efa0a42SZachary Turner // The max length of the next field is the minimum of all lengths that would 644efa0a42SZachary Turner // be allowed by any of the sub-records we're in. In practice, we can only 654efa0a42SZachary Turner // ever be at most 1 sub-record deep (in a FieldList), but this works for 664efa0a42SZachary Turner // the general case. 674efa0a42SZachary Turner uint32_t Offset = getCurrentOffset(); 684efa0a42SZachary Turner Optional<uint32_t> Min = Limits.front().bytesRemaining(Offset); 694efa0a42SZachary Turner for (auto X : makeArrayRef(Limits).drop_front()) { 704efa0a42SZachary Turner Optional<uint32_t> ThisMin = X.bytesRemaining(Offset); 714efa0a42SZachary Turner if (ThisMin.hasValue()) 724efa0a42SZachary Turner Min = (Min.hasValue()) ? std::min(*Min, *ThisMin) : *ThisMin; 734efa0a42SZachary Turner } 744efa0a42SZachary Turner assert(Min.hasValue() && "Every field must have a maximum length!"); 754efa0a42SZachary Turner 764efa0a42SZachary Turner return *Min; 774efa0a42SZachary Turner } 784efa0a42SZachary Turner 79ebd3ae83SZachary Turner Error CodeViewRecordIO::padToAlignment(uint32_t Align) { 80ebd3ae83SZachary Turner if (isReading()) 81ebd3ae83SZachary Turner return Reader->padToAlignment(Align); 82ebd3ae83SZachary Turner return Writer->padToAlignment(Align); 83ebd3ae83SZachary Turner } 84ebd3ae83SZachary Turner 857251ede7SZachary Turner Error CodeViewRecordIO::skipPadding() { 867251ede7SZachary Turner assert(!isWriting() && "Cannot skip padding while writing!"); 877251ede7SZachary Turner 887251ede7SZachary Turner if (Reader->bytesRemaining() == 0) 897251ede7SZachary Turner return Error::success(); 907251ede7SZachary Turner 917251ede7SZachary Turner uint8_t Leaf = Reader->peek(); 927251ede7SZachary Turner if (Leaf < LF_PAD0) 937251ede7SZachary Turner return Error::success(); 947251ede7SZachary Turner // Leaf is greater than 0xf0. We should advance by the number of bytes in 957251ede7SZachary Turner // the low 4 bits. 967251ede7SZachary Turner unsigned BytesToAdvance = Leaf & 0x0F; 977251ede7SZachary Turner return Reader->skip(BytesToAdvance); 987251ede7SZachary Turner } 997251ede7SZachary Turner 1006e407669SNilanjana Basu Error CodeViewRecordIO::mapByteVectorTail(ArrayRef<uint8_t> &Bytes, 1016e407669SNilanjana Basu const Twine &Comment) { 102faed8516SNilanjana Basu if (isStreaming()) { 1036e407669SNilanjana Basu emitComment(Comment); 104a55daa14SFangrui Song Streamer->emitBinaryData(toStringRef(Bytes)); 105faed8516SNilanjana Basu incrStreamedLen(Bytes.size()); 106faed8516SNilanjana Basu } else if (isWriting()) { 1077251ede7SZachary Turner if (auto EC = Writer->writeBytes(Bytes)) 1087251ede7SZachary Turner return EC; 1097251ede7SZachary Turner } else { 1107251ede7SZachary Turner if (auto EC = Reader->readBytes(Bytes, Reader->bytesRemaining())) 1117251ede7SZachary Turner return EC; 1127251ede7SZachary Turner } 1137251ede7SZachary Turner return Error::success(); 1147251ede7SZachary Turner } 1157251ede7SZachary Turner 1166e407669SNilanjana Basu Error CodeViewRecordIO::mapByteVectorTail(std::vector<uint8_t> &Bytes, 1176e407669SNilanjana Basu const Twine &Comment) { 11846225b19SZachary Turner ArrayRef<uint8_t> BytesRef(Bytes); 1196e407669SNilanjana Basu if (auto EC = mapByteVectorTail(BytesRef, Comment)) 12046225b19SZachary Turner return EC; 12146225b19SZachary Turner if (!isWriting()) 12246225b19SZachary Turner Bytes.assign(BytesRef.begin(), BytesRef.end()); 12346225b19SZachary Turner 12446225b19SZachary Turner return Error::success(); 12546225b19SZachary Turner } 12646225b19SZachary Turner 1276e407669SNilanjana Basu Error CodeViewRecordIO::mapInteger(TypeIndex &TypeInd, const Twine &Comment) { 128faed8516SNilanjana Basu if (isStreaming()) { 129ac3851c4SNilanjana Basu std::string TypeNameStr = Streamer->getTypeName(TypeInd); 130ac3851c4SNilanjana Basu if (!TypeNameStr.empty()) 131ac3851c4SNilanjana Basu emitComment(Comment + ": " + TypeNameStr); 132ac3851c4SNilanjana Basu else 1336e407669SNilanjana Basu emitComment(Comment); 13477497103SFangrui Song Streamer->emitIntValue(TypeInd.getIndex(), sizeof(TypeInd.getIndex())); 135faed8516SNilanjana Basu incrStreamedLen(sizeof(TypeInd.getIndex())); 136faed8516SNilanjana Basu } else if (isWriting()) { 137695ed56bSZachary Turner if (auto EC = Writer->writeInteger(TypeInd.getIndex())) 1387251ede7SZachary Turner return EC; 139faed8516SNilanjana Basu } else { 1407251ede7SZachary Turner uint32_t I; 141695ed56bSZachary Turner if (auto EC = Reader->readInteger(I)) 1427251ede7SZachary Turner return EC; 1437251ede7SZachary Turner TypeInd.setIndex(I); 144faed8516SNilanjana Basu } 1457251ede7SZachary Turner return Error::success(); 1467251ede7SZachary Turner } 1477251ede7SZachary Turner 1486e407669SNilanjana Basu Error CodeViewRecordIO::mapEncodedInteger(int64_t &Value, 1496e407669SNilanjana Basu const Twine &Comment) { 150faed8516SNilanjana Basu if (isStreaming()) { 151faed8516SNilanjana Basu if (Value >= 0) 1526e407669SNilanjana Basu emitEncodedUnsignedInteger(static_cast<uint64_t>(Value), Comment); 153faed8516SNilanjana Basu else 1546e407669SNilanjana Basu emitEncodedSignedInteger(Value, Comment); 155faed8516SNilanjana Basu } else if (isWriting()) { 1567251ede7SZachary Turner if (Value >= 0) { 1577251ede7SZachary Turner if (auto EC = writeEncodedUnsignedInteger(static_cast<uint64_t>(Value))) 1587251ede7SZachary Turner return EC; 1597251ede7SZachary Turner } else { 1607251ede7SZachary Turner if (auto EC = writeEncodedSignedInteger(Value)) 1617251ede7SZachary Turner return EC; 1627251ede7SZachary Turner } 1637251ede7SZachary Turner } else { 1647251ede7SZachary Turner APSInt N; 1657251ede7SZachary Turner if (auto EC = consume(*Reader, N)) 1667251ede7SZachary Turner return EC; 1677251ede7SZachary Turner Value = N.getExtValue(); 1687251ede7SZachary Turner } 1697251ede7SZachary Turner 1707251ede7SZachary Turner return Error::success(); 1717251ede7SZachary Turner } 1727251ede7SZachary Turner 1736e407669SNilanjana Basu Error CodeViewRecordIO::mapEncodedInteger(uint64_t &Value, 1746e407669SNilanjana Basu const Twine &Comment) { 175faed8516SNilanjana Basu if (isStreaming()) 1766e407669SNilanjana Basu emitEncodedUnsignedInteger(Value, Comment); 177faed8516SNilanjana Basu else if (isWriting()) { 1787251ede7SZachary Turner if (auto EC = writeEncodedUnsignedInteger(Value)) 1797251ede7SZachary Turner return EC; 1807251ede7SZachary Turner } else { 1817251ede7SZachary Turner APSInt N; 1827251ede7SZachary Turner if (auto EC = consume(*Reader, N)) 1837251ede7SZachary Turner return EC; 1847251ede7SZachary Turner Value = N.getZExtValue(); 1857251ede7SZachary Turner } 1867251ede7SZachary Turner return Error::success(); 1877251ede7SZachary Turner } 1887251ede7SZachary Turner 1896e407669SNilanjana Basu Error CodeViewRecordIO::mapEncodedInteger(APSInt &Value, const Twine &Comment) { 190faed8516SNilanjana Basu if (isStreaming()) { 191*f84c70a3SMatheus Izvekov // FIXME: We also need to handle big values here, but it's 192*f84c70a3SMatheus Izvekov // not clear how we can excercise this code path yet. 193faed8516SNilanjana Basu if (Value.isSigned()) 1946e407669SNilanjana Basu emitEncodedSignedInteger(Value.getSExtValue(), Comment); 195faed8516SNilanjana Basu else 1966e407669SNilanjana Basu emitEncodedUnsignedInteger(Value.getZExtValue(), Comment); 197faed8516SNilanjana Basu } else if (isWriting()) { 1987251ede7SZachary Turner if (Value.isSigned()) 199*f84c70a3SMatheus Izvekov return writeEncodedSignedInteger( 200*f84c70a3SMatheus Izvekov Value.isSingleWord() ? Value.getSExtValue() : INT64_MIN); 201*f84c70a3SMatheus Izvekov return writeEncodedUnsignedInteger(Value.getLimitedValue()); 202faed8516SNilanjana Basu } else 2037251ede7SZachary Turner return consume(*Reader, Value); 204faed8516SNilanjana Basu return Error::success(); 2057251ede7SZachary Turner } 2067251ede7SZachary Turner 2076e407669SNilanjana Basu Error CodeViewRecordIO::mapStringZ(StringRef &Value, const Twine &Comment) { 208faed8516SNilanjana Basu if (isStreaming()) { 209faed8516SNilanjana Basu auto NullTerminatedString = StringRef(Value.data(), Value.size() + 1); 2106e407669SNilanjana Basu emitComment(Comment); 211a55daa14SFangrui Song Streamer->emitBytes(NullTerminatedString); 212faed8516SNilanjana Basu incrStreamedLen(NullTerminatedString.size()); 213faed8516SNilanjana Basu } else if (isWriting()) { 2144efa0a42SZachary Turner // Truncate if we attempt to write too much. 2154efa0a42SZachary Turner StringRef S = Value.take_front(maxFieldLength() - 1); 216120faca4SZachary Turner if (auto EC = Writer->writeCString(S)) 2177251ede7SZachary Turner return EC; 2187251ede7SZachary Turner } else { 219120faca4SZachary Turner if (auto EC = Reader->readCString(Value)) 2207251ede7SZachary Turner return EC; 2217251ede7SZachary Turner } 2227251ede7SZachary Turner return Error::success(); 2237251ede7SZachary Turner } 2247251ede7SZachary Turner 2256e407669SNilanjana Basu Error CodeViewRecordIO::mapGuid(GUID &Guid, const Twine &Comment) { 2264efa0a42SZachary Turner constexpr uint32_t GuidSize = 16; 227faed8516SNilanjana Basu 228faed8516SNilanjana Basu if (isStreaming()) { 229faed8516SNilanjana Basu StringRef GuidSR = 230faed8516SNilanjana Basu StringRef((reinterpret_cast<const char *>(&Guid)), GuidSize); 2316e407669SNilanjana Basu emitComment(Comment); 232a55daa14SFangrui Song Streamer->emitBytes(GuidSR); 233faed8516SNilanjana Basu incrStreamedLen(GuidSize); 234faed8516SNilanjana Basu return Error::success(); 235faed8516SNilanjana Basu } 236faed8516SNilanjana Basu 2374efa0a42SZachary Turner if (maxFieldLength() < GuidSize) 2384efa0a42SZachary Turner return make_error<CodeViewError>(cv_error_code::insufficient_buffer); 2394efa0a42SZachary Turner 2407251ede7SZachary Turner if (isWriting()) { 24167653ee0SReid Kleckner if (auto EC = Writer->writeBytes(Guid.Guid)) 2427251ede7SZachary Turner return EC; 2437251ede7SZachary Turner } else { 24467653ee0SReid Kleckner ArrayRef<uint8_t> GuidBytes; 24567653ee0SReid Kleckner if (auto EC = Reader->readBytes(GuidBytes, GuidSize)) 2467251ede7SZachary Turner return EC; 24767653ee0SReid Kleckner memcpy(Guid.Guid, GuidBytes.data(), GuidSize); 2487251ede7SZachary Turner } 2497251ede7SZachary Turner return Error::success(); 2507251ede7SZachary Turner } 2517251ede7SZachary Turner 2526e407669SNilanjana Basu Error CodeViewRecordIO::mapStringZVectorZ(std::vector<StringRef> &Value, 2536e407669SNilanjana Basu const Twine &Comment) { 254faed8516SNilanjana Basu 255faed8516SNilanjana Basu if (!isReading()) { 2566e407669SNilanjana Basu emitComment(Comment); 25746225b19SZachary Turner for (auto V : Value) { 25846225b19SZachary Turner if (auto EC = mapStringZ(V)) 25946225b19SZachary Turner return EC; 26046225b19SZachary Turner } 261faed8516SNilanjana Basu uint8_t FinalZero = 0; 262faed8516SNilanjana Basu if (auto EC = mapInteger(FinalZero)) 26346225b19SZachary Turner return EC; 26446225b19SZachary Turner } else { 26546225b19SZachary Turner StringRef S; 26646225b19SZachary Turner if (auto EC = mapStringZ(S)) 26746225b19SZachary Turner return EC; 26846225b19SZachary Turner while (!S.empty()) { 26946225b19SZachary Turner Value.push_back(S); 27046225b19SZachary Turner if (auto EC = mapStringZ(S)) 27146225b19SZachary Turner return EC; 27246225b19SZachary Turner }; 27346225b19SZachary Turner } 27446225b19SZachary Turner return Error::success(); 27546225b19SZachary Turner } 27646225b19SZachary Turner 2776e407669SNilanjana Basu void CodeViewRecordIO::emitEncodedSignedInteger(const int64_t &Value, 2786e407669SNilanjana Basu const Twine &Comment) { 279*f84c70a3SMatheus Izvekov // FIXME: There are no test cases covering this function. 280*f84c70a3SMatheus Izvekov // This may be because we always consider enumerators to be unsigned. 281*f84c70a3SMatheus Izvekov // See FIXME at CodeViewDebug.cpp : CodeViewDebug::lowerTypeEnum. 282faed8516SNilanjana Basu if (Value >= std::numeric_limits<int8_t>::min()) { 28377497103SFangrui Song Streamer->emitIntValue(LF_CHAR, 2); 2846e407669SNilanjana Basu emitComment(Comment); 28577497103SFangrui Song Streamer->emitIntValue(Value, 1); 286faed8516SNilanjana Basu incrStreamedLen(3); 287faed8516SNilanjana Basu } else if (Value >= std::numeric_limits<int16_t>::min()) { 28877497103SFangrui Song Streamer->emitIntValue(LF_SHORT, 2); 2896e407669SNilanjana Basu emitComment(Comment); 29077497103SFangrui Song Streamer->emitIntValue(Value, 2); 291faed8516SNilanjana Basu incrStreamedLen(4); 292faed8516SNilanjana Basu } else if (Value >= std::numeric_limits<int32_t>::min()) { 29377497103SFangrui Song Streamer->emitIntValue(LF_LONG, 2); 2946e407669SNilanjana Basu emitComment(Comment); 29577497103SFangrui Song Streamer->emitIntValue(Value, 4); 296faed8516SNilanjana Basu incrStreamedLen(6); 297faed8516SNilanjana Basu } else { 29877497103SFangrui Song Streamer->emitIntValue(LF_QUADWORD, 2); 2996e407669SNilanjana Basu emitComment(Comment); 300*f84c70a3SMatheus Izvekov Streamer->emitIntValue(Value, 4); // FIXME: Why not 8 (size of quadword)? 301*f84c70a3SMatheus Izvekov incrStreamedLen(6); // FIXME: Why not 10 (8 + 2)? 302faed8516SNilanjana Basu } 303faed8516SNilanjana Basu } 304faed8516SNilanjana Basu 3056e407669SNilanjana Basu void CodeViewRecordIO::emitEncodedUnsignedInteger(const uint64_t &Value, 3066e407669SNilanjana Basu const Twine &Comment) { 307faed8516SNilanjana Basu if (Value < LF_NUMERIC) { 3086e407669SNilanjana Basu emitComment(Comment); 30977497103SFangrui Song Streamer->emitIntValue(Value, 2); 310faed8516SNilanjana Basu incrStreamedLen(2); 311faed8516SNilanjana Basu } else if (Value <= std::numeric_limits<uint16_t>::max()) { 31277497103SFangrui Song Streamer->emitIntValue(LF_USHORT, 2); 3136e407669SNilanjana Basu emitComment(Comment); 31477497103SFangrui Song Streamer->emitIntValue(Value, 2); 315faed8516SNilanjana Basu incrStreamedLen(4); 316faed8516SNilanjana Basu } else if (Value <= std::numeric_limits<uint32_t>::max()) { 31777497103SFangrui Song Streamer->emitIntValue(LF_ULONG, 2); 3186e407669SNilanjana Basu emitComment(Comment); 31977497103SFangrui Song Streamer->emitIntValue(Value, 4); 320faed8516SNilanjana Basu incrStreamedLen(6); 321faed8516SNilanjana Basu } else { 322*f84c70a3SMatheus Izvekov // FIXME: There are no test cases covering this block. 32377497103SFangrui Song Streamer->emitIntValue(LF_UQUADWORD, 2); 3246e407669SNilanjana Basu emitComment(Comment); 32577497103SFangrui Song Streamer->emitIntValue(Value, 8); 326*f84c70a3SMatheus Izvekov incrStreamedLen(6); // FIXME: Why not 10 (8 + 2)? 327faed8516SNilanjana Basu } 328faed8516SNilanjana Basu } 329faed8516SNilanjana Basu 3307251ede7SZachary Turner Error CodeViewRecordIO::writeEncodedSignedInteger(const int64_t &Value) { 3317251ede7SZachary Turner if (Value >= std::numeric_limits<int8_t>::min()) { 332695ed56bSZachary Turner if (auto EC = Writer->writeInteger<uint16_t>(LF_CHAR)) 3337251ede7SZachary Turner return EC; 334695ed56bSZachary Turner if (auto EC = Writer->writeInteger<int8_t>(Value)) 3357251ede7SZachary Turner return EC; 3367251ede7SZachary Turner } else if (Value >= std::numeric_limits<int16_t>::min()) { 337695ed56bSZachary Turner if (auto EC = Writer->writeInteger<uint16_t>(LF_SHORT)) 3387251ede7SZachary Turner return EC; 339695ed56bSZachary Turner if (auto EC = Writer->writeInteger<int16_t>(Value)) 3407251ede7SZachary Turner return EC; 3417251ede7SZachary Turner } else if (Value >= std::numeric_limits<int32_t>::min()) { 342695ed56bSZachary Turner if (auto EC = Writer->writeInteger<uint16_t>(LF_LONG)) 3437251ede7SZachary Turner return EC; 344695ed56bSZachary Turner if (auto EC = Writer->writeInteger<int32_t>(Value)) 3457251ede7SZachary Turner return EC; 3467251ede7SZachary Turner } else { 347695ed56bSZachary Turner if (auto EC = Writer->writeInteger<uint16_t>(LF_QUADWORD)) 3487251ede7SZachary Turner return EC; 349695ed56bSZachary Turner if (auto EC = Writer->writeInteger(Value)) 3507251ede7SZachary Turner return EC; 3517251ede7SZachary Turner } 3527251ede7SZachary Turner return Error::success(); 3537251ede7SZachary Turner } 3547251ede7SZachary Turner 3557251ede7SZachary Turner Error CodeViewRecordIO::writeEncodedUnsignedInteger(const uint64_t &Value) { 3567251ede7SZachary Turner if (Value < LF_NUMERIC) { 357695ed56bSZachary Turner if (auto EC = Writer->writeInteger<uint16_t>(Value)) 3587251ede7SZachary Turner return EC; 3597251ede7SZachary Turner } else if (Value <= std::numeric_limits<uint16_t>::max()) { 360695ed56bSZachary Turner if (auto EC = Writer->writeInteger<uint16_t>(LF_USHORT)) 3617251ede7SZachary Turner return EC; 362695ed56bSZachary Turner if (auto EC = Writer->writeInteger<uint16_t>(Value)) 3637251ede7SZachary Turner return EC; 3647251ede7SZachary Turner } else if (Value <= std::numeric_limits<uint32_t>::max()) { 365695ed56bSZachary Turner if (auto EC = Writer->writeInteger<uint16_t>(LF_ULONG)) 3667251ede7SZachary Turner return EC; 367695ed56bSZachary Turner if (auto EC = Writer->writeInteger<uint32_t>(Value)) 3687251ede7SZachary Turner return EC; 3697251ede7SZachary Turner } else { 370695ed56bSZachary Turner if (auto EC = Writer->writeInteger<uint16_t>(LF_UQUADWORD)) 3717251ede7SZachary Turner return EC; 372695ed56bSZachary Turner if (auto EC = Writer->writeInteger(Value)) 3737251ede7SZachary Turner return EC; 3747251ede7SZachary Turner } 3757251ede7SZachary Turner 3767251ede7SZachary Turner return Error::success(); 3777251ede7SZachary Turner } 378