//===- 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/DbiModuleDescriptor.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 <algorithm>
#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];
}
