//===- DbiStreamBuilder.cpp - PDB Dbi Stream Creation -----------*- 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
//
//===----------------------------------------------------------------------===//
//
// The data structures defined in this file are based on the reference
// implementation which is available at
// https://github.com/Microsoft/microsoft-pdb/blob/master/PDB/dbi/gsi.cpp
//
//===----------------------------------------------------------------------===//

#include "llvm/DebugInfo/PDB/Native/GSIStreamBuilder.h"
#include "llvm/DebugInfo/CodeView/RecordName.h"
#include "llvm/DebugInfo/CodeView/SymbolDeserializer.h"
#include "llvm/DebugInfo/CodeView/SymbolRecord.h"
#include "llvm/DebugInfo/CodeView/SymbolSerializer.h"
#include "llvm/DebugInfo/MSF/MSFBuilder.h"
#include "llvm/DebugInfo/MSF/MSFCommon.h"
#include "llvm/DebugInfo/MSF/MappedBlockStream.h"
#include "llvm/DebugInfo/PDB/Native/GlobalsStream.h"
#include "llvm/DebugInfo/PDB/Native/Hash.h"
#include "llvm/Support/BinaryItemStream.h"
#include "llvm/Support/BinaryStreamWriter.h"
#include "llvm/Support/Parallel.h"
#include "llvm/Support/xxhash.h"
#include <algorithm>
#include <vector>

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

// Helper class for building the public and global PDB hash table buckets.
struct llvm::pdb::GSIHashStreamBuilder {
  // Sum of the size of all public or global records.
  uint32_t RecordByteSize = 0;

  std::vector<PSHashRecord> HashRecords;

  // The hash bitmap has `ceil((IPHR_HASH + 1) / 32)` words in it. The
  // reference implementation builds a hash table with IPHR_HASH buckets in it.
  // The last bucket is used to link together free hash table cells in a linked
  // list, but it is always empty in the compressed, on-disk format. However,
  // the bitmap must have a bit for it.
  std::array<support::ulittle32_t, (IPHR_HASH + 32) / 32> HashBitmap;

  std::vector<support::ulittle32_t> HashBuckets;

  uint32_t calculateSerializedLength() const;
  Error commit(BinaryStreamWriter &Writer);

  void finalizePublicBuckets();
  void finalizeGlobalBuckets(uint32_t RecordZeroOffset);

  // Assign public and global symbol records into hash table buckets.
  // Modifies the list of records to store the bucket index, but does not
  // change the order.
  void finalizeBuckets(uint32_t RecordZeroOffset,
                       MutableArrayRef<BulkPublic> Globals);
};

// DenseMapInfo implementation for deduplicating symbol records.
struct llvm::pdb::SymbolDenseMapInfo {
  static inline CVSymbol getEmptyKey() {
    static CVSymbol Empty;
    return Empty;
  }
  static inline CVSymbol getTombstoneKey() {
    static CVSymbol Tombstone(
        DenseMapInfo<ArrayRef<uint8_t>>::getTombstoneKey());
    return Tombstone;
  }
  static unsigned getHashValue(const CVSymbol &Val) {
    return xxHash64(Val.RecordData);
  }
  static bool isEqual(const CVSymbol &LHS, const CVSymbol &RHS) {
    return LHS.RecordData == RHS.RecordData;
  }
};

namespace {
LLVM_PACKED_START
struct PublicSym32Layout {
  RecordPrefix Prefix;
  PublicSym32Header Pub;
  // char Name[];
};
LLVM_PACKED_END
} // namespace

// Calculate how much memory this public needs when serialized.
static uint32_t sizeOfPublic(const BulkPublic &Pub) {
  uint32_t NameLen = Pub.NameLen;
  NameLen = std::min(NameLen,
                     uint32_t(MaxRecordLength - sizeof(PublicSym32Layout) - 1));
  return alignTo(sizeof(PublicSym32Layout) + NameLen + 1, 4);
}

static CVSymbol serializePublic(uint8_t *Mem, const BulkPublic &Pub) {
  // Assume the caller has allocated sizeOfPublic bytes.
  uint32_t NameLen = std::min(
      Pub.NameLen, uint32_t(MaxRecordLength - sizeof(PublicSym32Layout) - 1));
  size_t Size = alignTo(sizeof(PublicSym32Layout) + NameLen + 1, 4);
  assert(Size == sizeOfPublic(Pub));
  auto *FixedMem = reinterpret_cast<PublicSym32Layout *>(Mem);
  FixedMem->Prefix.RecordKind = static_cast<uint16_t>(codeview::S_PUB32);
  FixedMem->Prefix.RecordLen = static_cast<uint16_t>(Size - 2);
  FixedMem->Pub.Flags = Pub.Flags;
  FixedMem->Pub.Offset = Pub.Offset;
  FixedMem->Pub.Segment = Pub.Segment;
  char *NameMem = reinterpret_cast<char *>(FixedMem + 1);
  memcpy(NameMem, Pub.Name, NameLen);
  // Zero the null terminator and remaining bytes.
  memset(&NameMem[NameLen], 0, Size - sizeof(PublicSym32Layout) - NameLen);
  return CVSymbol(makeArrayRef(reinterpret_cast<uint8_t *>(Mem), Size));
}

uint32_t GSIHashStreamBuilder::calculateSerializedLength() const {
  uint32_t Size = sizeof(GSIHashHeader);
  Size += HashRecords.size() * sizeof(PSHashRecord);
  Size += HashBitmap.size() * sizeof(uint32_t);
  Size += HashBuckets.size() * sizeof(uint32_t);
  return Size;
}

Error GSIHashStreamBuilder::commit(BinaryStreamWriter &Writer) {
  GSIHashHeader Header;
  Header.VerSignature = GSIHashHeader::HdrSignature;
  Header.VerHdr = GSIHashHeader::HdrVersion;
  Header.HrSize = HashRecords.size() * sizeof(PSHashRecord);
  Header.NumBuckets = HashBitmap.size() * 4 + HashBuckets.size() * 4;

  if (auto EC = Writer.writeObject(Header))
    return EC;

  if (auto EC = Writer.writeArray(makeArrayRef(HashRecords)))
    return EC;
  if (auto EC = Writer.writeArray(makeArrayRef(HashBitmap)))
    return EC;
  if (auto EC = Writer.writeArray(makeArrayRef(HashBuckets)))
    return EC;
  return Error::success();
}

static bool isAsciiString(StringRef S) {
  return llvm::all_of(S, [](char C) { return unsigned(C) < 0x80; });
}

// See `caseInsensitiveComparePchPchCchCch` in gsi.cpp
static int gsiRecordCmp(StringRef S1, StringRef S2) {
  size_t LS = S1.size();
  size_t RS = S2.size();
  // Shorter strings always compare less than longer strings.
  if (LS != RS)
    return (LS > RS) - (LS < RS);

  // If either string contains non ascii characters, memcmp them.
  if (LLVM_UNLIKELY(!isAsciiString(S1) || !isAsciiString(S2)))
    return memcmp(S1.data(), S2.data(), LS);

  // Both strings are ascii, perform a case-insensitive comparison.
  return S1.compare_lower(S2.data());
}

void GSIStreamBuilder::finalizePublicBuckets() {
  PSH->finalizeBuckets(0, Publics);
}

void GSIStreamBuilder::finalizeGlobalBuckets(uint32_t RecordZeroOffset) {
  // Build up a list of globals to be bucketed. Use the BulkPublic data
  // structure for this purpose, even though these are global records, not
  // public records. Most of the same fields are required:
  // - Name
  // - NameLen
  // - SymOffset
  // - BucketIdx
  // The dead fields are Offset, Segment, and Flags.
  std::vector<BulkPublic> Records;
  Records.resize(Globals.size());
  uint32_t SymOffset = RecordZeroOffset;
  for (size_t I = 0, E = Globals.size(); I < E; ++I) {
    StringRef Name = getSymbolName(Globals[I]);
    Records[I].Name = Name.data();
    Records[I].NameLen = Name.size();
    Records[I].SymOffset = SymOffset;
    SymOffset += Globals[I].length();
  }

  GSH->finalizeBuckets(RecordZeroOffset, Records);
}

void GSIHashStreamBuilder::finalizeBuckets(
    uint32_t RecordZeroOffset, MutableArrayRef<BulkPublic> Records) {
  // Hash every name in parallel.
  parallelForEachN(0, Records.size(), [&](size_t I) {
    Records[I].setBucketIdx(hashStringV1(Records[I].Name) % IPHR_HASH);
  });

  // Count up the size of each bucket. Then, use an exclusive prefix sum to
  // calculate the bucket start offsets. This is C++17 std::exclusive_scan, but
  // we can't use it yet.
  uint32_t BucketStarts[IPHR_HASH] = {0};
  for (const BulkPublic &P : Records)
    ++BucketStarts[P.BucketIdx];
  uint32_t Sum = 0;
  for (uint32_t &B : BucketStarts) {
    uint32_t Size = B;
    B = Sum;
    Sum += Size;
  }

  // Place globals into the hash table in bucket order. When placing a global,
  // update the bucket start. Every hash table slot should be filled. Always use
  // a refcount of one for now.
  HashRecords.resize(Records.size());
  uint32_t BucketCursors[IPHR_HASH];
  memcpy(BucketCursors, BucketStarts, sizeof(BucketCursors));
  for (int I = 0, E = Records.size(); I < E; ++I) {
    uint32_t HashIdx = BucketCursors[Records[I].BucketIdx]++;
    HashRecords[HashIdx].Off = I;
    HashRecords[HashIdx].CRef = 1;
  }

  // Within the buckets, sort each bucket by memcmp of the symbol's name.  It's
  // important that we use the same sorting algorithm as is used by the
  // reference implementation to ensure that the search for a record within a
  // bucket can properly early-out when it detects the record won't be found.
  // The algorithm used here corresponds to the function
  // caseInsensitiveComparePchPchCchCch in the reference implementation.
  parallelForEachN(0, IPHR_HASH, [&](size_t I) {
    auto B = HashRecords.begin() + BucketStarts[I];
    auto E = HashRecords.begin() + BucketCursors[I];
    if (B == E)
      return;
    auto BucketCmp = [Records](const PSHashRecord &LHash,
                               const PSHashRecord &RHash) {
      const BulkPublic &L = Records[uint32_t(LHash.Off)];
      const BulkPublic &R = Records[uint32_t(RHash.Off)];
      assert(L.BucketIdx == R.BucketIdx);
      int Cmp = gsiRecordCmp(L.getName(), R.getName());
      if (Cmp != 0)
        return Cmp < 0;
      // This comparison is necessary to make the sorting stable in the presence
      // of two static globals with the same name. The easiest way to observe
      // this is with S_LDATA32 records.
      return L.SymOffset < R.SymOffset;
    };
    llvm::sort(B, E, BucketCmp);

    // After we are done sorting, replace the global indices with the stream
    // offsets of each global. Add one when writing symbol offsets to disk.
    // See GSI1::fixSymRecs.
    for (PSHashRecord &HRec : make_range(B, E))
      HRec.Off = Records[uint32_t(HRec.Off)].SymOffset + 1;
  });

  // For each non-empty bucket, push the bucket start offset into HashBuckets
  // and set a bit in the hash bitmap.
  for (uint32_t I = 0; I < HashBitmap.size(); ++I) {
    uint32_t Word = 0;
    for (uint32_t J = 0; J < 32; ++J) {
      // Skip empty buckets.
      uint32_t BucketIdx = I * 32 + J;
      if (BucketIdx >= IPHR_HASH ||
          BucketStarts[BucketIdx] == BucketCursors[BucketIdx])
        continue;
      Word |= (1U << J);

      // Calculate what the offset of the first hash record in the chain would
      // be if it were inflated to contain 32-bit pointers. On a 32-bit system,
      // each record would be 12 bytes. See HROffsetCalc in gsi.h.
      const int SizeOfHROffsetCalc = 12;
      ulittle32_t ChainStartOff =
          ulittle32_t(BucketStarts[BucketIdx] * SizeOfHROffsetCalc);
      HashBuckets.push_back(ChainStartOff);
    }
    HashBitmap[I] = Word;
  }
}

GSIStreamBuilder::GSIStreamBuilder(msf::MSFBuilder &Msf)
    : Msf(Msf), PSH(std::make_unique<GSIHashStreamBuilder>()),
      GSH(std::make_unique<GSIHashStreamBuilder>()) {}

GSIStreamBuilder::~GSIStreamBuilder() {}

uint32_t GSIStreamBuilder::calculatePublicsHashStreamSize() const {
  uint32_t Size = 0;
  Size += sizeof(PublicsStreamHeader);
  Size += PSH->calculateSerializedLength();
  Size += Publics.size() * sizeof(uint32_t); // AddrMap
  // FIXME: Add thunk map and section offsets for incremental linking.

  return Size;
}

uint32_t GSIStreamBuilder::calculateGlobalsHashStreamSize() const {
  return GSH->calculateSerializedLength();
}

Error GSIStreamBuilder::finalizeMsfLayout() {
  // First we write public symbol records, then we write global symbol records.
  finalizePublicBuckets();
  finalizeGlobalBuckets(PSH->RecordByteSize);

  Expected<uint32_t> Idx = Msf.addStream(calculateGlobalsHashStreamSize());
  if (!Idx)
    return Idx.takeError();
  GlobalsStreamIndex = *Idx;

  Idx = Msf.addStream(calculatePublicsHashStreamSize());
  if (!Idx)
    return Idx.takeError();
  PublicsStreamIndex = *Idx;

  uint32_t RecordBytes = PSH->RecordByteSize + GSH->RecordByteSize;

  Idx = Msf.addStream(RecordBytes);
  if (!Idx)
    return Idx.takeError();
  RecordStreamIndex = *Idx;
  return Error::success();
}

void GSIStreamBuilder::addPublicSymbols(std::vector<BulkPublic> &&PublicsIn) {
  assert(Publics.empty() && PSH->RecordByteSize == 0 &&
         "publics can only be added once");
  Publics = std::move(PublicsIn);

  // Sort the symbols by name. PDBs contain lots of symbols, so use parallelism.
  parallelSort(Publics, [](const BulkPublic &L, const BulkPublic &R) {
    return L.getName() < R.getName();
  });

  // Assign offsets and calculate the length of the public symbol records.
  uint32_t SymOffset = 0;
  for (BulkPublic &Pub : Publics) {
    Pub.SymOffset = SymOffset;
    SymOffset += sizeOfPublic(Pub);
  }

  // Remember the length of the public stream records.
  PSH->RecordByteSize = SymOffset;
}

void GSIStreamBuilder::addGlobalSymbol(const ProcRefSym &Sym) {
  serializeAndAddGlobal(Sym);
}

void GSIStreamBuilder::addGlobalSymbol(const DataSym &Sym) {
  serializeAndAddGlobal(Sym);
}

void GSIStreamBuilder::addGlobalSymbol(const ConstantSym &Sym) {
  serializeAndAddGlobal(Sym);
}

template <typename T>
void GSIStreamBuilder::serializeAndAddGlobal(const T &Symbol) {
  T Copy(Symbol);
  addGlobalSymbol(SymbolSerializer::writeOneSymbol(Copy, Msf.getAllocator(),
                                                   CodeViewContainer::Pdb));
}

void GSIStreamBuilder::addGlobalSymbol(const codeview::CVSymbol &Symbol) {
  // Ignore duplicate typedefs and constants.
  if (Symbol.kind() == S_UDT || Symbol.kind() == S_CONSTANT) {
    auto Iter = GlobalsSeen.insert(Symbol);
    if (!Iter.second)
      return;
  }
  GSH->RecordByteSize += Symbol.length();
  Globals.push_back(Symbol);
}

// Serialize each public and write it.
static Error writePublics(BinaryStreamWriter &Writer,
                          ArrayRef<BulkPublic> Publics) {
  std::vector<uint8_t> Storage;
  for (const BulkPublic &Pub : Publics) {
    Storage.resize(sizeOfPublic(Pub));
    serializePublic(Storage.data(), Pub);
    if (Error E = Writer.writeBytes(Storage))
      return E;
  }
  return Error::success();
}

static Error writeRecords(BinaryStreamWriter &Writer,
                          ArrayRef<CVSymbol> Records) {
  BinaryItemStream<CVSymbol> ItemStream(support::endianness::little);
  ItemStream.setItems(Records);
  BinaryStreamRef RecordsRef(ItemStream);
  return Writer.writeStreamRef(RecordsRef);
}

Error GSIStreamBuilder::commitSymbolRecordStream(
    WritableBinaryStreamRef Stream) {
  BinaryStreamWriter Writer(Stream);

  // Write public symbol records first, followed by global symbol records.  This
  // must match the order that we assume in finalizeMsfLayout when computing
  // PSHZero and GSHZero.
  if (auto EC = writePublics(Writer, Publics))
    return EC;
  if (auto EC = writeRecords(Writer, Globals))
    return EC;

  return Error::success();
}

static std::vector<support::ulittle32_t>
computeAddrMap(ArrayRef<BulkPublic> Publics) {
  // Build a parallel vector of indices into the Publics vector, and sort it by
  // address.
  std::vector<ulittle32_t> PubAddrMap;
  PubAddrMap.reserve(Publics.size());
  for (int I = 0, E = Publics.size(); I < E; ++I)
    PubAddrMap.push_back(ulittle32_t(I));

  auto AddrCmp = [Publics](const ulittle32_t &LIdx, const ulittle32_t &RIdx) {
    const BulkPublic &L = Publics[LIdx];
    const BulkPublic &R = Publics[RIdx];
    if (L.Segment != R.Segment)
      return L.Segment < R.Segment;
    if (L.Offset != R.Offset)
      return L.Offset < R.Offset;
    // parallelSort is unstable, so we have to do name comparison to ensure
    // that two names for the same location come out in a deterministic order.
    return L.getName() < R.getName();
  };
  parallelSort(PubAddrMap, AddrCmp);

  // Rewrite the public symbol indices into symbol offsets.
  for (ulittle32_t &Entry : PubAddrMap)
    Entry = Publics[Entry].SymOffset;
  return PubAddrMap;
}

Error GSIStreamBuilder::commitPublicsHashStream(
    WritableBinaryStreamRef Stream) {
  BinaryStreamWriter Writer(Stream);
  PublicsStreamHeader Header;

  // FIXME: Fill these in. They are for incremental linking.
  Header.SymHash = PSH->calculateSerializedLength();
  Header.AddrMap = Publics.size() * 4;
  Header.NumThunks = 0;
  Header.SizeOfThunk = 0;
  Header.ISectThunkTable = 0;
  memset(Header.Padding, 0, sizeof(Header.Padding));
  Header.OffThunkTable = 0;
  Header.NumSections = 0;
  if (auto EC = Writer.writeObject(Header))
    return EC;

  if (auto EC = PSH->commit(Writer))
    return EC;

  std::vector<support::ulittle32_t> PubAddrMap = computeAddrMap(Publics);
  assert(PubAddrMap.size() == Publics.size());
  if (auto EC = Writer.writeArray(makeArrayRef(PubAddrMap)))
    return EC;

  return Error::success();
}

Error GSIStreamBuilder::commitGlobalsHashStream(
    WritableBinaryStreamRef Stream) {
  BinaryStreamWriter Writer(Stream);
  return GSH->commit(Writer);
}

Error GSIStreamBuilder::commit(const msf::MSFLayout &Layout,
                               WritableBinaryStreamRef Buffer) {
  auto GS = WritableMappedBlockStream::createIndexedStream(
      Layout, Buffer, getGlobalsStreamIndex(), Msf.getAllocator());
  auto PS = WritableMappedBlockStream::createIndexedStream(
      Layout, Buffer, getPublicsStreamIndex(), Msf.getAllocator());
  auto PRS = WritableMappedBlockStream::createIndexedStream(
      Layout, Buffer, getRecordStreamIndex(), Msf.getAllocator());

  if (auto EC = commitSymbolRecordStream(*PRS))
    return EC;
  if (auto EC = commitGlobalsHashStream(*GS))
    return EC;
  if (auto EC = commitPublicsHashStream(*PS))
    return EC;
  return Error::success();
}
