//===- PDBFile.cpp - Low level interface to a PDB file ----------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "llvm/DebugInfo/PDB/Native/PDBFile.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/DebugInfo/MSF/MSFCommon.h"
#include "llvm/DebugInfo/MSF/MappedBlockStream.h"
#include "llvm/DebugInfo/PDB/Native/DbiStream.h"
#include "llvm/DebugInfo/PDB/Native/GlobalsStream.h"
#include "llvm/DebugInfo/PDB/Native/InfoStream.h"
#include "llvm/DebugInfo/PDB/Native/PDBStringTable.h"
#include "llvm/DebugInfo/PDB/Native/PublicsStream.h"
#include "llvm/DebugInfo/PDB/Native/RawError.h"
#include "llvm/DebugInfo/PDB/Native/SymbolStream.h"
#include "llvm/DebugInfo/PDB/Native/TpiStream.h"
#include "llvm/Support/BinaryStream.h"
#include "llvm/Support/BinaryStreamArray.h"
#include "llvm/Support/BinaryStreamReader.h"
#include "llvm/Support/Endian.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/Path.h"
#include <algorithm>
#include <cassert>
#include <cstdint>

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

namespace {
typedef FixedStreamArray<support::ulittle32_t> ulittle_array;
} // end anonymous namespace

PDBFile::PDBFile(StringRef Path, std::unique_ptr<BinaryStream> PdbFileBuffer,
                 BumpPtrAllocator &Allocator)
    : FilePath(Path), Allocator(Allocator), Buffer(std::move(PdbFileBuffer)) {}

PDBFile::~PDBFile() = default;

StringRef PDBFile::getFilePath() const { return FilePath; }

StringRef PDBFile::getFileDirectory() const {
  return sys::path::parent_path(FilePath);
}

uint32_t PDBFile::getBlockSize() const { return ContainerLayout.SB->BlockSize; }

uint32_t PDBFile::getFreeBlockMapBlock() const {
  return ContainerLayout.SB->FreeBlockMapBlock;
}

uint32_t PDBFile::getBlockCount() const {
  return ContainerLayout.SB->NumBlocks;
}

uint32_t PDBFile::getNumDirectoryBytes() const {
  return ContainerLayout.SB->NumDirectoryBytes;
}

uint32_t PDBFile::getBlockMapIndex() const {
  return ContainerLayout.SB->BlockMapAddr;
}

uint32_t PDBFile::getUnknown1() const { return ContainerLayout.SB->Unknown1; }

uint32_t PDBFile::getNumDirectoryBlocks() const {
  return msf::bytesToBlocks(ContainerLayout.SB->NumDirectoryBytes,
                            ContainerLayout.SB->BlockSize);
}

uint64_t PDBFile::getBlockMapOffset() const {
  return (uint64_t)ContainerLayout.SB->BlockMapAddr *
         ContainerLayout.SB->BlockSize;
}

uint32_t PDBFile::getNumStreams() const {
  return ContainerLayout.StreamSizes.size();
}

uint32_t PDBFile::getMaxStreamSize() const {
  return *std::max_element(ContainerLayout.StreamSizes.begin(),
                           ContainerLayout.StreamSizes.end());
}

uint32_t PDBFile::getStreamByteSize(uint32_t StreamIndex) const {
  return ContainerLayout.StreamSizes[StreamIndex];
}

ArrayRef<support::ulittle32_t>
PDBFile::getStreamBlockList(uint32_t StreamIndex) const {
  return ContainerLayout.StreamMap[StreamIndex];
}

uint32_t PDBFile::getFileSize() const { return Buffer->getLength(); }

Expected<ArrayRef<uint8_t>> PDBFile::getBlockData(uint32_t BlockIndex,
                                                  uint32_t NumBytes) const {
  uint64_t StreamBlockOffset = msf::blockToOffset(BlockIndex, getBlockSize());

  ArrayRef<uint8_t> Result;
  if (auto EC = Buffer->readBytes(StreamBlockOffset, NumBytes, Result))
    return std::move(EC);
  return Result;
}

Error PDBFile::setBlockData(uint32_t BlockIndex, uint32_t Offset,
                            ArrayRef<uint8_t> Data) const {
  return make_error<RawError>(raw_error_code::not_writable,
                              "PDBFile is immutable");
}

Error PDBFile::parseFileHeaders() {
  BinaryStreamReader Reader(*Buffer);

  // Initialize SB.
  const msf::SuperBlock *SB = nullptr;
  if (auto EC = Reader.readObject(SB)) {
    consumeError(std::move(EC));
    return make_error<RawError>(raw_error_code::corrupt_file,
                                "Does not contain superblock");
  }

  if (auto EC = msf::validateSuperBlock(*SB))
    return EC;

  if (Buffer->getLength() % SB->BlockSize != 0)
    return make_error<RawError>(raw_error_code::corrupt_file,
                                "File size is not a multiple of block size");
  ContainerLayout.SB = SB;

  // Initialize Free Page Map.
  ContainerLayout.FreePageMap.resize(SB->NumBlocks);
  // The Fpm exists either at block 1 or block 2 of the MSF.  However, this
  // allows for a maximum of getBlockSize() * 8 blocks bits in the Fpm, and
  // thusly an equal number of total blocks in the file.  For a block size
  // of 4KiB (very common), this would yield 32KiB total blocks in file, for a
  // maximum file size of 32KiB * 4KiB = 128MiB.  Obviously this won't do, so
  // the Fpm is split across the file at `getBlockSize()` intervals.  As a
  // result, every block whose index is of the form |{1,2} + getBlockSize() * k|
  // for any non-negative integer k is an Fpm block.  In theory, we only really
  // need to reserve blocks of the form |{1,2} + getBlockSize() * 8 * k|, but
  // current versions of the MSF format already expect the Fpm to be arranged
  // at getBlockSize() intervals, so we have to be compatible.
  // See the function fpmPn() for more information:
  // https://github.com/Microsoft/microsoft-pdb/blob/master/PDB/msf/msf.cpp#L489
  auto FpmStream =
      MappedBlockStream::createFpmStream(ContainerLayout, *Buffer, Allocator);
  BinaryStreamReader FpmReader(*FpmStream);
  ArrayRef<uint8_t> FpmBytes;
  if (auto EC = FpmReader.readBytes(FpmBytes, FpmReader.bytesRemaining()))
    return EC;
  uint32_t BlocksRemaining = getBlockCount();
  uint32_t BI = 0;
  for (auto Byte : FpmBytes) {
    uint32_t BlocksThisByte = std::min(BlocksRemaining, 8U);
    for (uint32_t I = 0; I < BlocksThisByte; ++I) {
      if (Byte & (1 << I))
        ContainerLayout.FreePageMap[BI] = true;
      --BlocksRemaining;
      ++BI;
    }
  }

  Reader.setOffset(getBlockMapOffset());
  if (auto EC = Reader.readArray(ContainerLayout.DirectoryBlocks,
                                 getNumDirectoryBlocks()))
    return EC;

  return Error::success();
}

Error PDBFile::parseStreamData() {
  assert(ContainerLayout.SB);
  if (DirectoryStream)
    return Error::success();

  uint32_t NumStreams = 0;

  // Normally you can't use a MappedBlockStream without having fully parsed the
  // PDB file, because it accesses the directory and various other things, which
  // is exactly what we are attempting to parse.  By specifying a custom
  // subclass of IPDBStreamData which only accesses the fields that have already
  // been parsed, we can avoid this and reuse MappedBlockStream.
  auto DS = MappedBlockStream::createDirectoryStream(ContainerLayout, *Buffer,
                                                     Allocator);
  BinaryStreamReader Reader(*DS);
  if (auto EC = Reader.readInteger(NumStreams))
    return EC;

  if (auto EC = Reader.readArray(ContainerLayout.StreamSizes, NumStreams))
    return EC;
  for (uint32_t I = 0; I < NumStreams; ++I) {
    uint32_t StreamSize = getStreamByteSize(I);
    // FIXME: What does StreamSize ~0U mean?
    uint64_t NumExpectedStreamBlocks =
        StreamSize == UINT32_MAX
            ? 0
            : msf::bytesToBlocks(StreamSize, ContainerLayout.SB->BlockSize);

    // For convenience, we store the block array contiguously.  This is because
    // if someone calls setStreamMap(), it is more convenient to be able to call
    // it with an ArrayRef instead of setting up a StreamRef.  Since the
    // DirectoryStream is cached in the class and thus lives for the life of the
    // class, we can be guaranteed that readArray() will return a stable
    // reference, even if it has to allocate from its internal pool.
    ArrayRef<support::ulittle32_t> Blocks;
    if (auto EC = Reader.readArray(Blocks, NumExpectedStreamBlocks))
      return EC;
    for (uint32_t Block : Blocks) {
      uint64_t BlockEndOffset =
          (uint64_t)(Block + 1) * ContainerLayout.SB->BlockSize;
      if (BlockEndOffset > getFileSize())
        return make_error<RawError>(raw_error_code::corrupt_file,
                                    "Stream block map is corrupt.");
    }
    ContainerLayout.StreamMap.push_back(Blocks);
  }

  // We should have read exactly SB->NumDirectoryBytes bytes.
  assert(Reader.bytesRemaining() == 0);
  DirectoryStream = std::move(DS);
  return Error::success();
}

ArrayRef<support::ulittle32_t> PDBFile::getDirectoryBlockArray() const {
  return ContainerLayout.DirectoryBlocks;
}

std::unique_ptr<MappedBlockStream> PDBFile::createIndexedStream(uint16_t SN) {
  if (SN == kInvalidStreamIndex)
    return nullptr;
  return MappedBlockStream::createIndexedStream(ContainerLayout, *Buffer, SN,
                                                Allocator);
}

MSFStreamLayout PDBFile::getStreamLayout(uint32_t StreamIdx) const {
  MSFStreamLayout Result;
  auto Blocks = getStreamBlockList(StreamIdx);
  Result.Blocks.assign(Blocks.begin(), Blocks.end());
  Result.Length = getStreamByteSize(StreamIdx);
  return Result;
}

msf::MSFStreamLayout PDBFile::getFpmStreamLayout() const {
  return msf::getFpmStreamLayout(ContainerLayout);
}

Expected<GlobalsStream &> PDBFile::getPDBGlobalsStream() {
  if (!Globals) {
    auto DbiS = getPDBDbiStream();
    if (!DbiS)
      return DbiS.takeError();

    auto GlobalS = safelyCreateIndexedStream(
        ContainerLayout, *Buffer, DbiS->getGlobalSymbolStreamIndex());
    if (!GlobalS)
      return GlobalS.takeError();
    auto TempGlobals = llvm::make_unique<GlobalsStream>(std::move(*GlobalS));
    if (auto EC = TempGlobals->reload())
      return std::move(EC);
    Globals = std::move(TempGlobals);
  }
  return *Globals;
}

Expected<InfoStream &> PDBFile::getPDBInfoStream() {
  if (!Info) {
    auto InfoS = safelyCreateIndexedStream(ContainerLayout, *Buffer, StreamPDB);
    if (!InfoS)
      return InfoS.takeError();
    auto TempInfo = llvm::make_unique<InfoStream>(std::move(*InfoS));
    if (auto EC = TempInfo->reload())
      return std::move(EC);
    Info = std::move(TempInfo);
  }
  return *Info;
}

Expected<DbiStream &> PDBFile::getPDBDbiStream() {
  if (!Dbi) {
    auto DbiS = safelyCreateIndexedStream(ContainerLayout, *Buffer, StreamDBI);
    if (!DbiS)
      return DbiS.takeError();
    auto TempDbi = llvm::make_unique<DbiStream>(std::move(*DbiS));
    if (auto EC = TempDbi->reload(this))
      return std::move(EC);
    Dbi = std::move(TempDbi);
  }
  return *Dbi;
}

Expected<TpiStream &> PDBFile::getPDBTpiStream() {
  if (!Tpi) {
    auto TpiS = safelyCreateIndexedStream(ContainerLayout, *Buffer, StreamTPI);
    if (!TpiS)
      return TpiS.takeError();
    auto TempTpi = llvm::make_unique<TpiStream>(*this, std::move(*TpiS));
    if (auto EC = TempTpi->reload())
      return std::move(EC);
    Tpi = std::move(TempTpi);
  }
  return *Tpi;
}

Expected<TpiStream &> PDBFile::getPDBIpiStream() {
  if (!Ipi) {
    if (!hasPDBIpiStream())
      return make_error<RawError>(raw_error_code::no_stream);

    auto IpiS = safelyCreateIndexedStream(ContainerLayout, *Buffer, StreamIPI);
    if (!IpiS)
      return IpiS.takeError();
    auto TempIpi = llvm::make_unique<TpiStream>(*this, std::move(*IpiS));
    if (auto EC = TempIpi->reload())
      return std::move(EC);
    Ipi = std::move(TempIpi);
  }
  return *Ipi;
}

Expected<PublicsStream &> PDBFile::getPDBPublicsStream() {
  if (!Publics) {
    auto DbiS = getPDBDbiStream();
    if (!DbiS)
      return DbiS.takeError();

    auto PublicS = safelyCreateIndexedStream(
        ContainerLayout, *Buffer, DbiS->getPublicSymbolStreamIndex());
    if (!PublicS)
      return PublicS.takeError();
    auto TempPublics = llvm::make_unique<PublicsStream>(std::move(*PublicS));
    if (auto EC = TempPublics->reload())
      return std::move(EC);
    Publics = std::move(TempPublics);
  }
  return *Publics;
}

Expected<SymbolStream &> PDBFile::getPDBSymbolStream() {
  if (!Symbols) {
    auto DbiS = getPDBDbiStream();
    if (!DbiS)
      return DbiS.takeError();

    uint32_t SymbolStreamNum = DbiS->getSymRecordStreamIndex();
    auto SymbolS =
        safelyCreateIndexedStream(ContainerLayout, *Buffer, SymbolStreamNum);
    if (!SymbolS)
      return SymbolS.takeError();

    auto TempSymbols = llvm::make_unique<SymbolStream>(std::move(*SymbolS));
    if (auto EC = TempSymbols->reload())
      return std::move(EC);
    Symbols = std::move(TempSymbols);
  }
  return *Symbols;
}

Expected<PDBStringTable &> PDBFile::getStringTable() {
  if (!Strings) {
    auto IS = getPDBInfoStream();
    if (!IS)
      return IS.takeError();

    Expected<uint32_t> ExpectedNSI = IS->getNamedStreamIndex("/names");
    if (!ExpectedNSI)
      return ExpectedNSI.takeError();
    uint32_t NameStreamIndex = *ExpectedNSI;

    auto NS =
        safelyCreateIndexedStream(ContainerLayout, *Buffer, NameStreamIndex);
    if (!NS)
      return NS.takeError();

    auto N = llvm::make_unique<PDBStringTable>();
    BinaryStreamReader Reader(**NS);
    if (auto EC = N->reload(Reader))
      return std::move(EC);
    assert(Reader.bytesRemaining() == 0);
    StringTableStream = std::move(*NS);
    Strings = std::move(N);
  }
  return *Strings;
}

uint32_t PDBFile::getPointerSize() {
  auto DbiS = getPDBDbiStream();
  if (!DbiS)
    return 0;
  PDB_Machine Machine = DbiS->getMachineType();
  if (Machine == PDB_Machine::Amd64)
    return 8;
  return 4;
}

bool PDBFile::hasPDBDbiStream() const { return StreamDBI < getNumStreams(); }

bool PDBFile::hasPDBGlobalsStream() {
  auto DbiS = getPDBDbiStream();
  if (!DbiS) {
    consumeError(DbiS.takeError());
    return false;
  }

  return DbiS->getGlobalSymbolStreamIndex() < getNumStreams();
}

bool PDBFile::hasPDBInfoStream() const { return StreamPDB < getNumStreams(); }

bool PDBFile::hasPDBIpiStream() const {
  if (!hasPDBInfoStream())
    return false;

  if (StreamIPI >= getNumStreams())
    return false;

  auto &InfoStream = cantFail(const_cast<PDBFile *>(this)->getPDBInfoStream());
  return InfoStream.containsIdStream();
}

bool PDBFile::hasPDBPublicsStream() {
  auto DbiS = getPDBDbiStream();
  if (!DbiS) {
    consumeError(DbiS.takeError());
    return false;
  }
  return DbiS->getPublicSymbolStreamIndex() < getNumStreams();
}

bool PDBFile::hasPDBSymbolStream() {
  auto DbiS = getPDBDbiStream();
  if (!DbiS)
    return false;
  return DbiS->getSymRecordStreamIndex() < getNumStreams();
}

bool PDBFile::hasPDBTpiStream() const { return StreamTPI < getNumStreams(); }

bool PDBFile::hasPDBStringTable() {
  auto IS = getPDBInfoStream();
  if (!IS)
    return false;
  Expected<uint32_t> ExpectedNSI = IS->getNamedStreamIndex("/names");
  if (!ExpectedNSI) {
    consumeError(ExpectedNSI.takeError());
    return false;
  }
  assert(*ExpectedNSI < getNumStreams());
  return true;
}

/// Wrapper around MappedBlockStream::createIndexedStream() that checks if a
/// stream with that index actually exists.  If it does not, the return value
/// will have an MSFError with code msf_error_code::no_stream.  Else, the return
/// value will contain the stream returned by createIndexedStream().
Expected<std::unique_ptr<MappedBlockStream>>
PDBFile::safelyCreateIndexedStream(const MSFLayout &Layout,
                                   BinaryStreamRef MsfData,
                                   uint32_t StreamIndex) const {
  if (StreamIndex >= getNumStreams())
    return make_error<RawError>(raw_error_code::no_stream);
  return MappedBlockStream::createIndexedStream(Layout, MsfData, StreamIndex,
                                                Allocator);
}
