//===- DbiStream.cpp - PDB Dbi Stream (Stream 3) Access -------------------===//
//
// 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/PDB/Native/DbiStream.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/DebugInfo/MSF/MappedBlockStream.h"
#include "llvm/DebugInfo/PDB/Native/ISectionContribVisitor.h"
#include "llvm/DebugInfo/PDB/Native/PDBFile.h"
#include "llvm/DebugInfo/PDB/Native/RawConstants.h"
#include "llvm/DebugInfo/PDB/Native/RawError.h"
#include "llvm/DebugInfo/PDB/Native/RawTypes.h"
#include "llvm/DebugInfo/PDB/PDBTypes.h"
#include "llvm/Object/COFF.h"
#include "llvm/Support/BinaryStreamArray.h"
#include "llvm/Support/BinaryStreamReader.h"
#include "llvm/Support/Error.h"
#include <cstddef>
#include <cstdint>

using namespace llvm;
using namespace llvm::codeview;
using namespace llvm::msf;
using namespace llvm::pdb;
using namespace llvm::support;

template <typename ContribType>
static Error loadSectionContribs(FixedStreamArray<ContribType> &Output,
                                 BinaryStreamReader &Reader) {
  if (Reader.bytesRemaining() % sizeof(ContribType) != 0)
    return make_error<RawError>(
        raw_error_code::corrupt_file,
        "Invalid number of bytes of section contributions");

  uint32_t Count = Reader.bytesRemaining() / sizeof(ContribType);
  if (auto EC = Reader.readArray(Output, Count))
    return EC;
  return Error::success();
}

DbiStream::DbiStream(std::unique_ptr<BinaryStream> Stream)
    : Stream(std::move(Stream)), Header(nullptr) {}

DbiStream::~DbiStream() = default;

Error DbiStream::reload(PDBFile *Pdb) {
  BinaryStreamReader Reader(*Stream);

  if (Stream->getLength() < sizeof(DbiStreamHeader))
    return make_error<RawError>(raw_error_code::corrupt_file,
                                "DBI Stream does not contain a header.");
  if (auto EC = Reader.readObject(Header))
    return make_error<RawError>(raw_error_code::corrupt_file,
                                "DBI Stream does not contain a header.");

  if (Header->VersionSignature != -1)
    return make_error<RawError>(raw_error_code::corrupt_file,
                                "Invalid DBI version signature.");

  // Require at least version 7, which should be present in all PDBs
  // produced in the last decade and allows us to avoid having to
  // special case all kinds of complicated arcane formats.
  if (Header->VersionHeader < PdbDbiV70)
    return make_error<RawError>(raw_error_code::feature_unsupported,
                                "Unsupported DBI version.");

  if (Stream->getLength() !=
      sizeof(DbiStreamHeader) + Header->ModiSubstreamSize +
          Header->SecContrSubstreamSize + Header->SectionMapSize +
          Header->FileInfoSize + Header->TypeServerSize +
          Header->OptionalDbgHdrSize + Header->ECSubstreamSize)
    return make_error<RawError>(raw_error_code::corrupt_file,
                                "DBI Length does not equal sum of substreams.");

  // Only certain substreams are guaranteed to be aligned.  Validate
  // them here.
  if (Header->ModiSubstreamSize % sizeof(uint32_t) != 0)
    return make_error<RawError>(raw_error_code::corrupt_file,
                                "DBI MODI substream not aligned.");
  if (Header->SecContrSubstreamSize % sizeof(uint32_t) != 0)
    return make_error<RawError>(
        raw_error_code::corrupt_file,
        "DBI section contribution substream not aligned.");
  if (Header->SectionMapSize % sizeof(uint32_t) != 0)
    return make_error<RawError>(raw_error_code::corrupt_file,
                                "DBI section map substream not aligned.");
  if (Header->FileInfoSize % sizeof(uint32_t) != 0)
    return make_error<RawError>(raw_error_code::corrupt_file,
                                "DBI file info substream not aligned.");
  if (Header->TypeServerSize % sizeof(uint32_t) != 0)
    return make_error<RawError>(raw_error_code::corrupt_file,
                                "DBI type server substream not aligned.");

  if (auto EC = Reader.readSubstream(ModiSubstream, Header->ModiSubstreamSize))
    return EC;

  if (auto EC = Reader.readSubstream(SecContrSubstream,
                                     Header->SecContrSubstreamSize))
    return EC;
  if (auto EC = Reader.readSubstream(SecMapSubstream, Header->SectionMapSize))
    return EC;
  if (auto EC = Reader.readSubstream(FileInfoSubstream, Header->FileInfoSize))
    return EC;
  if (auto EC =
          Reader.readSubstream(TypeServerMapSubstream, Header->TypeServerSize))
    return EC;
  if (auto EC = Reader.readSubstream(ECSubstream, Header->ECSubstreamSize))
    return EC;
  if (auto EC = Reader.readArray(
          DbgStreams, Header->OptionalDbgHdrSize / sizeof(ulittle16_t)))
    return EC;

  if (auto EC = Modules.initialize(ModiSubstream.StreamData,
                                   FileInfoSubstream.StreamData))
    return EC;

  if (auto EC = initializeSectionContributionData())
    return EC;
  if (auto EC = initializeSectionHeadersData(Pdb))
    return EC;
  if (auto EC = initializeSectionMapData())
    return EC;
  if (auto EC = initializeOldFpoRecords(Pdb))
    return EC;
  if (auto EC = initializeNewFpoRecords(Pdb))
     return EC;

  if (Reader.bytesRemaining() > 0)
    return make_error<RawError>(raw_error_code::corrupt_file,
                                "Found unexpected bytes in DBI Stream.");

  if (!ECSubstream.empty()) {
    BinaryStreamReader ECReader(ECSubstream.StreamData);
    if (auto EC = ECNames.reload(ECReader))
      return EC;
  }

  return Error::success();
}

PdbRaw_DbiVer DbiStream::getDbiVersion() const {
  uint32_t Value = Header->VersionHeader;
  return static_cast<PdbRaw_DbiVer>(Value);
}

uint32_t DbiStream::getAge() const { return Header->Age; }

uint16_t DbiStream::getPublicSymbolStreamIndex() const {
  return Header->PublicSymbolStreamIndex;
}

uint16_t DbiStream::getGlobalSymbolStreamIndex() const {
  return Header->GlobalSymbolStreamIndex;
}

uint16_t DbiStream::getFlags() const { return Header->Flags; }

bool DbiStream::isIncrementallyLinked() const {
  return (Header->Flags & DbiFlags::FlagIncrementalMask) != 0;
}

bool DbiStream::hasCTypes() const {
  return (Header->Flags & DbiFlags::FlagHasCTypesMask) != 0;
}

bool DbiStream::isStripped() const {
  return (Header->Flags & DbiFlags::FlagStrippedMask) != 0;
}

uint16_t DbiStream::getBuildNumber() const { return Header->BuildNumber; }

uint16_t DbiStream::getBuildMajorVersion() const {
  return (Header->BuildNumber & DbiBuildNo::BuildMajorMask) >>
         DbiBuildNo::BuildMajorShift;
}

uint16_t DbiStream::getBuildMinorVersion() const {
  return (Header->BuildNumber & DbiBuildNo::BuildMinorMask) >>
         DbiBuildNo::BuildMinorShift;
}

uint16_t DbiStream::getPdbDllRbld() const { return Header->PdbDllRbld; }

uint32_t DbiStream::getPdbDllVersion() const { return Header->PdbDllVersion; }

uint32_t DbiStream::getSymRecordStreamIndex() const {
  return Header->SymRecordStreamIndex;
}

PDB_Machine DbiStream::getMachineType() const {
  uint16_t Machine = Header->MachineType;
  return static_cast<PDB_Machine>(Machine);
}

FixedStreamArray<object::coff_section> DbiStream::getSectionHeaders() const {
  return SectionHeaders;
}

bool DbiStream::hasOldFpoRecords() const { return OldFpoStream != nullptr; }

FixedStreamArray<object::FpoData> DbiStream::getOldFpoRecords() const {
  return OldFpoRecords;
}

bool DbiStream::hasNewFpoRecords() const { return NewFpoStream != nullptr; }

const DebugFrameDataSubsectionRef &DbiStream::getNewFpoRecords() const {
  return NewFpoRecords;
}

const DbiModuleList &DbiStream::modules() const { return Modules; }

FixedStreamArray<SecMapEntry> DbiStream::getSectionMap() const {
  return SectionMap;
}

void DbiStream::visitSectionContributions(
    ISectionContribVisitor &Visitor) const {
  if (!SectionContribs.empty()) {
    assert(SectionContribVersion == DbiSecContribVer60);
    for (auto &SC : SectionContribs)
      Visitor.visit(SC);
  } else if (!SectionContribs2.empty()) {
    assert(SectionContribVersion == DbiSecContribV2);
    for (auto &SC : SectionContribs2)
      Visitor.visit(SC);
  }
}

Expected<StringRef> DbiStream::getECName(uint32_t NI) const {
  return ECNames.getStringForID(NI);
}

Error DbiStream::initializeSectionContributionData() {
  if (SecContrSubstream.empty())
    return Error::success();

  BinaryStreamReader SCReader(SecContrSubstream.StreamData);
  if (auto EC = SCReader.readEnum(SectionContribVersion))
    return EC;

  if (SectionContribVersion == DbiSecContribVer60)
    return loadSectionContribs<SectionContrib>(SectionContribs, SCReader);
  if (SectionContribVersion == DbiSecContribV2)
    return loadSectionContribs<SectionContrib2>(SectionContribs2, SCReader);

  return make_error<RawError>(raw_error_code::feature_unsupported,
                              "Unsupported DBI Section Contribution version");
}

// Initializes this->SectionHeaders.
Error DbiStream::initializeSectionHeadersData(PDBFile *Pdb) {
  Expected<std::unique_ptr<msf::MappedBlockStream>> ExpectedStream =
      createIndexedStreamForHeaderType(Pdb, DbgHeaderType::SectionHdr);
  if (auto EC = ExpectedStream.takeError())
    return EC;

  auto &SHS = *ExpectedStream;
  if (!SHS)
    return Error::success();

  size_t StreamLen = SHS->getLength();
  if (StreamLen % sizeof(object::coff_section))
    return make_error<RawError>(raw_error_code::corrupt_file,
                                "Corrupted section header stream.");

  size_t NumSections = StreamLen / sizeof(object::coff_section);
  BinaryStreamReader Reader(*SHS);
  if (auto EC = Reader.readArray(SectionHeaders, NumSections))
    return make_error<RawError>(raw_error_code::corrupt_file,
                                "Could not read a bitmap.");

  SectionHeaderStream = std::move(SHS);
  return Error::success();
}

// Initializes this->Fpos.
Error DbiStream::initializeOldFpoRecords(PDBFile *Pdb) {
  Expected<std::unique_ptr<msf::MappedBlockStream>> ExpectedStream =
      createIndexedStreamForHeaderType(Pdb, DbgHeaderType::FPO);
  if (auto EC = ExpectedStream.takeError())
    return EC;

  auto &FS = *ExpectedStream;
  if (!FS)
    return Error::success();

  size_t StreamLen = FS->getLength();
  if (StreamLen % sizeof(object::FpoData))
    return make_error<RawError>(raw_error_code::corrupt_file,
                                "Corrupted Old FPO stream.");

  size_t NumRecords = StreamLen / sizeof(object::FpoData);
  BinaryStreamReader Reader(*FS);
  if (auto EC = Reader.readArray(OldFpoRecords, NumRecords))
    return make_error<RawError>(raw_error_code::corrupt_file,
                                "Corrupted Old FPO stream.");
  OldFpoStream = std::move(FS);
  return Error::success();
}

Error DbiStream::initializeNewFpoRecords(PDBFile *Pdb) {
  Expected<std::unique_ptr<msf::MappedBlockStream>> ExpectedStream =
      createIndexedStreamForHeaderType(Pdb, DbgHeaderType::NewFPO);
  if (auto EC = ExpectedStream.takeError())
    return EC;

  auto &FS = *ExpectedStream;
  if (!FS)
    return Error::success();

  if (auto EC = NewFpoRecords.initialize(*FS))
    return EC;

  NewFpoStream = std::move(FS);
  return Error::success();
}

Expected<std::unique_ptr<msf::MappedBlockStream>>
DbiStream::createIndexedStreamForHeaderType(PDBFile *Pdb,
                                            DbgHeaderType Type) const {
  if (!Pdb)
    return nullptr;

  if (DbgStreams.empty())
    return nullptr;

  uint32_t StreamNum = getDebugStreamIndex(Type);

  // This means there is no such stream.
  if (StreamNum == kInvalidStreamIndex)
    return nullptr;

  return Pdb->safelyCreateIndexedStream(StreamNum);
}

BinarySubstreamRef DbiStream::getSectionContributionData() const {
  return SecContrSubstream;
}

BinarySubstreamRef DbiStream::getSecMapSubstreamData() const {
  return SecMapSubstream;
}

BinarySubstreamRef DbiStream::getModiSubstreamData() const {
  return ModiSubstream;
}

BinarySubstreamRef DbiStream::getFileInfoSubstreamData() const {
  return FileInfoSubstream;
}

BinarySubstreamRef DbiStream::getTypeServerMapSubstreamData() const {
  return TypeServerMapSubstream;
}

BinarySubstreamRef DbiStream::getECSubstreamData() const { return ECSubstream; }

Error DbiStream::initializeSectionMapData() {
  if (SecMapSubstream.empty())
    return Error::success();

  BinaryStreamReader SMReader(SecMapSubstream.StreamData);
  const SecMapHeader *Header;
  if (auto EC = SMReader.readObject(Header))
    return EC;
  if (auto EC = SMReader.readArray(SectionMap, Header->SecCount))
    return EC;
  return Error::success();
}

uint32_t DbiStream::getDebugStreamIndex(DbgHeaderType Type) const {
  uint16_t T = static_cast<uint16_t>(Type);
  if (T >= DbgStreams.size())
    return kInvalidStreamIndex;
  return DbgStreams[T];
}
