//===- CodeViewRecordIO.cpp -------------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "llvm/DebugInfo/CodeView/CodeViewRecordIO.h"
#include "llvm/DebugInfo/CodeView/CodeView.h"
#include "llvm/DebugInfo/CodeView/RecordSerialization.h"
#include "llvm/Support/BinaryStreamReader.h"
#include "llvm/Support/BinaryStreamWriter.h"

using namespace llvm;
using namespace llvm::codeview;

Error CodeViewRecordIO::beginRecord(Optional<uint32_t> MaxLength) {
  RecordLimit Limit;
  Limit.MaxLength = MaxLength;
  Limit.BeginOffset = getCurrentOffset();
  Limits.push_back(Limit);
  return Error::success();
}

Error CodeViewRecordIO::endRecord() {
  assert(!Limits.empty() && "Not in a record!");
  Limits.pop_back();
  // We would like to assert that we actually read / wrote all the bytes that we
  // expected to for this record, but unfortunately we can't do this.  Some
  // producers such as MASM over-allocate for certain types of records and
  // commit the extraneous data, so when reading we can't be sure every byte
  // will have been read.  And when writing we over-allocate temporarily since
  // we don't know how big the record is until we're finished writing it, so
  // even though we don't commit the extraneous data, we still can't guarantee
  // we're at the end of the allocated data.

  if (isStreaming()) {
    // For streaming mode, add padding to align with 4 byte boundaries for each
    // record
    uint32_t Align = getStreamedLen() % 4;
    if (Align == 0)
      return Error::success();

    int PaddingBytes = 4 - Align;
    while (PaddingBytes > 0) {
      char Pad = static_cast<uint8_t>(LF_PAD0 + PaddingBytes);
      StringRef BytesSR = StringRef(&Pad, sizeof(Pad));
      Streamer->emitBytes(BytesSR);
      --PaddingBytes;
    }
    resetStreamedLen();
  }
  return Error::success();
}

uint32_t CodeViewRecordIO::maxFieldLength() const {
  if (isStreaming())
    return 0;

  assert(!Limits.empty() && "Not in a record!");

  // The max length of the next field is the minimum of all lengths that would
  // be allowed by any of the sub-records we're in.  In practice, we can only
  // ever be at most 1 sub-record deep (in a FieldList), but this works for
  // the general case.
  uint32_t Offset = getCurrentOffset();
  Optional<uint32_t> Min = Limits.front().bytesRemaining(Offset);
  for (auto X : makeArrayRef(Limits).drop_front()) {
    Optional<uint32_t> ThisMin = X.bytesRemaining(Offset);
    if (ThisMin.hasValue())
      Min = (Min.hasValue()) ? std::min(*Min, *ThisMin) : *ThisMin;
  }
  assert(Min.hasValue() && "Every field must have a maximum length!");

  return *Min;
}

Error CodeViewRecordIO::padToAlignment(uint32_t Align) {
  if (isReading())
    return Reader->padToAlignment(Align);
  return Writer->padToAlignment(Align);
}

Error CodeViewRecordIO::skipPadding() {
  assert(!isWriting() && "Cannot skip padding while writing!");

  if (Reader->bytesRemaining() == 0)
    return Error::success();

  uint8_t Leaf = Reader->peek();
  if (Leaf < LF_PAD0)
    return Error::success();
  // Leaf is greater than 0xf0. We should advance by the number of bytes in
  // the low 4 bits.
  unsigned BytesToAdvance = Leaf & 0x0F;
  return Reader->skip(BytesToAdvance);
}

Error CodeViewRecordIO::mapByteVectorTail(ArrayRef<uint8_t> &Bytes,
                                          const Twine &Comment) {
  if (isStreaming()) {
    emitComment(Comment);
    Streamer->emitBinaryData(toStringRef(Bytes));
    incrStreamedLen(Bytes.size());
  } else if (isWriting()) {
    if (auto EC = Writer->writeBytes(Bytes))
      return EC;
  } else {
    if (auto EC = Reader->readBytes(Bytes, Reader->bytesRemaining()))
      return EC;
  }
  return Error::success();
}

Error CodeViewRecordIO::mapByteVectorTail(std::vector<uint8_t> &Bytes,
                                          const Twine &Comment) {
  ArrayRef<uint8_t> BytesRef(Bytes);
  if (auto EC = mapByteVectorTail(BytesRef, Comment))
    return EC;
  if (!isWriting())
    Bytes.assign(BytesRef.begin(), BytesRef.end());

  return Error::success();
}

Error CodeViewRecordIO::mapInteger(TypeIndex &TypeInd, const Twine &Comment) {
  if (isStreaming()) {
    std::string TypeNameStr = Streamer->getTypeName(TypeInd);
    if (!TypeNameStr.empty())
      emitComment(Comment + ": " + TypeNameStr);
    else
      emitComment(Comment);
    Streamer->emitIntValue(TypeInd.getIndex(), sizeof(TypeInd.getIndex()));
    incrStreamedLen(sizeof(TypeInd.getIndex()));
  } else if (isWriting()) {
    if (auto EC = Writer->writeInteger(TypeInd.getIndex()))
      return EC;
  } else {
    uint32_t I;
    if (auto EC = Reader->readInteger(I))
      return EC;
    TypeInd.setIndex(I);
  }
  return Error::success();
}

Error CodeViewRecordIO::mapEncodedInteger(int64_t &Value,
                                          const Twine &Comment) {
  if (isStreaming()) {
    if (Value >= 0)
      emitEncodedUnsignedInteger(static_cast<uint64_t>(Value), Comment);
    else
      emitEncodedSignedInteger(Value, Comment);
  } else if (isWriting()) {
    if (Value >= 0) {
      if (auto EC = writeEncodedUnsignedInteger(static_cast<uint64_t>(Value)))
        return EC;
    } else {
      if (auto EC = writeEncodedSignedInteger(Value))
        return EC;
    }
  } else {
    APSInt N;
    if (auto EC = consume(*Reader, N))
      return EC;
    Value = N.getExtValue();
  }

  return Error::success();
}

Error CodeViewRecordIO::mapEncodedInteger(uint64_t &Value,
                                          const Twine &Comment) {
  if (isStreaming())
    emitEncodedUnsignedInteger(Value, Comment);
  else if (isWriting()) {
    if (auto EC = writeEncodedUnsignedInteger(Value))
      return EC;
  } else {
    APSInt N;
    if (auto EC = consume(*Reader, N))
      return EC;
    Value = N.getZExtValue();
  }
  return Error::success();
}

Error CodeViewRecordIO::mapEncodedInteger(APSInt &Value, const Twine &Comment) {
  if (isStreaming()) {
    // FIXME: We also need to handle big values here, but it's
    //        not clear how we can excercise this code path yet.
    if (Value.isSigned())
      emitEncodedSignedInteger(Value.getSExtValue(), Comment);
    else
      emitEncodedUnsignedInteger(Value.getZExtValue(), Comment);
  } else if (isWriting()) {
    if (Value.isSigned())
      return writeEncodedSignedInteger(
          Value.isSingleWord() ? Value.getSExtValue() : INT64_MIN);
    return writeEncodedUnsignedInteger(Value.getLimitedValue());
  } else
    return consume(*Reader, Value);
  return Error::success();
}

Error CodeViewRecordIO::mapStringZ(StringRef &Value, const Twine &Comment) {
  if (isStreaming()) {
    auto NullTerminatedString = StringRef(Value.data(), Value.size() + 1);
    emitComment(Comment);
    Streamer->emitBytes(NullTerminatedString);
    incrStreamedLen(NullTerminatedString.size());
  } else if (isWriting()) {
    // Truncate if we attempt to write too much.
    StringRef S = Value.take_front(maxFieldLength() - 1);
    if (auto EC = Writer->writeCString(S))
      return EC;
  } else {
    if (auto EC = Reader->readCString(Value))
      return EC;
  }
  return Error::success();
}

Error CodeViewRecordIO::mapGuid(GUID &Guid, const Twine &Comment) {
  constexpr uint32_t GuidSize = 16;

  if (isStreaming()) {
    StringRef GuidSR =
        StringRef((reinterpret_cast<const char *>(&Guid)), GuidSize);
    emitComment(Comment);
    Streamer->emitBytes(GuidSR);
    incrStreamedLen(GuidSize);
    return Error::success();
  }

  if (maxFieldLength() < GuidSize)
    return make_error<CodeViewError>(cv_error_code::insufficient_buffer);

  if (isWriting()) {
    if (auto EC = Writer->writeBytes(Guid.Guid))
      return EC;
  } else {
    ArrayRef<uint8_t> GuidBytes;
    if (auto EC = Reader->readBytes(GuidBytes, GuidSize))
      return EC;
    memcpy(Guid.Guid, GuidBytes.data(), GuidSize);
  }
  return Error::success();
}

Error CodeViewRecordIO::mapStringZVectorZ(std::vector<StringRef> &Value,
                                          const Twine &Comment) {

  if (!isReading()) {
    emitComment(Comment);
    for (auto V : Value) {
      if (auto EC = mapStringZ(V))
        return EC;
    }
    uint8_t FinalZero = 0;
    if (auto EC = mapInteger(FinalZero))
      return EC;
  } else {
    StringRef S;
    if (auto EC = mapStringZ(S))
      return EC;
    while (!S.empty()) {
      Value.push_back(S);
      if (auto EC = mapStringZ(S))
        return EC;
    };
  }
  return Error::success();
}

void CodeViewRecordIO::emitEncodedSignedInteger(const int64_t &Value,
                                                const Twine &Comment) {
  // FIXME: There are no test cases covering this function.
  // This may be because we always consider enumerators to be unsigned.
  // See FIXME at CodeViewDebug.cpp : CodeViewDebug::lowerTypeEnum.
  if (Value >= std::numeric_limits<int8_t>::min()) {
    Streamer->emitIntValue(LF_CHAR, 2);
    emitComment(Comment);
    Streamer->emitIntValue(Value, 1);
    incrStreamedLen(3);
  } else if (Value >= std::numeric_limits<int16_t>::min()) {
    Streamer->emitIntValue(LF_SHORT, 2);
    emitComment(Comment);
    Streamer->emitIntValue(Value, 2);
    incrStreamedLen(4);
  } else if (Value >= std::numeric_limits<int32_t>::min()) {
    Streamer->emitIntValue(LF_LONG, 2);
    emitComment(Comment);
    Streamer->emitIntValue(Value, 4);
    incrStreamedLen(6);
  } else {
    Streamer->emitIntValue(LF_QUADWORD, 2);
    emitComment(Comment);
    Streamer->emitIntValue(Value, 4); // FIXME: Why not 8 (size of quadword)?
    incrStreamedLen(6);               // FIXME: Why not 10 (8 + 2)?
  }
}

void CodeViewRecordIO::emitEncodedUnsignedInteger(const uint64_t &Value,
                                                  const Twine &Comment) {
  if (Value < LF_NUMERIC) {
    emitComment(Comment);
    Streamer->emitIntValue(Value, 2);
    incrStreamedLen(2);
  } else if (Value <= std::numeric_limits<uint16_t>::max()) {
    Streamer->emitIntValue(LF_USHORT, 2);
    emitComment(Comment);
    Streamer->emitIntValue(Value, 2);
    incrStreamedLen(4);
  } else if (Value <= std::numeric_limits<uint32_t>::max()) {
    Streamer->emitIntValue(LF_ULONG, 2);
    emitComment(Comment);
    Streamer->emitIntValue(Value, 4);
    incrStreamedLen(6);
  } else {
    // FIXME: There are no test cases covering this block.
    Streamer->emitIntValue(LF_UQUADWORD, 2);
    emitComment(Comment);
    Streamer->emitIntValue(Value, 8);
    incrStreamedLen(6); // FIXME: Why not 10 (8 + 2)?
  }
}

Error CodeViewRecordIO::writeEncodedSignedInteger(const int64_t &Value) {
  if (Value >= std::numeric_limits<int8_t>::min()) {
    if (auto EC = Writer->writeInteger<uint16_t>(LF_CHAR))
      return EC;
    if (auto EC = Writer->writeInteger<int8_t>(Value))
      return EC;
  } else if (Value >= std::numeric_limits<int16_t>::min()) {
    if (auto EC = Writer->writeInteger<uint16_t>(LF_SHORT))
      return EC;
    if (auto EC = Writer->writeInteger<int16_t>(Value))
      return EC;
  } else if (Value >= std::numeric_limits<int32_t>::min()) {
    if (auto EC = Writer->writeInteger<uint16_t>(LF_LONG))
      return EC;
    if (auto EC = Writer->writeInteger<int32_t>(Value))
      return EC;
  } else {
    if (auto EC = Writer->writeInteger<uint16_t>(LF_QUADWORD))
      return EC;
    if (auto EC = Writer->writeInteger(Value))
      return EC;
  }
  return Error::success();
}

Error CodeViewRecordIO::writeEncodedUnsignedInteger(const uint64_t &Value) {
  if (Value < LF_NUMERIC) {
    if (auto EC = Writer->writeInteger<uint16_t>(Value))
      return EC;
  } else if (Value <= std::numeric_limits<uint16_t>::max()) {
    if (auto EC = Writer->writeInteger<uint16_t>(LF_USHORT))
      return EC;
    if (auto EC = Writer->writeInteger<uint16_t>(Value))
      return EC;
  } else if (Value <= std::numeric_limits<uint32_t>::max()) {
    if (auto EC = Writer->writeInteger<uint16_t>(LF_ULONG))
      return EC;
    if (auto EC = Writer->writeInteger<uint32_t>(Value))
      return EC;
  } else {
    if (auto EC = Writer->writeInteger<uint16_t>(LF_UQUADWORD))
      return EC;
    if (auto EC = Writer->writeInteger(Value))
      return EC;
  }

  return Error::success();
}
