//===- DXContainerPDB.cpp - DirectX PDB writer pass -----------------------===//
//
// 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 "DirectX.h"
#include "MCTargetDesc/DirectXContainerObjectWriter.h"
#include "llvm/ADT/ScopeExit.h"
#include "llvm/ADT/StringSet.h"
#include "llvm/BinaryFormat/DXContainer.h"
#include "llvm/DebugInfo/CodeView/GUID.h"
#include "llvm/DebugInfo/MSF/MSFBuilder.h"
#include "llvm/DebugInfo/PDB/Native/InfoStreamBuilder.h"
#include "llvm/DebugInfo/PDB/Native/PDBFileBuilder.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/Module.h"
#include "llvm/MC/MCDXContainerWriter.h"
#include "llvm/Pass.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/IOSandbox.h"
#include "llvm/Support/VirtualFileSystem.h"
#include "llvm/Transforms/Utils/ModuleUtils.h"

using namespace llvm;

namespace {

class DXContainerPDB : public ModulePass, MCDXContainerBaseWriter {
  Module *M = nullptr;
  SmallVector<MCDXContainerPart> Parts;

  void reset() {
    M = nullptr;
    Parts.clear();
  }

public:
  static char ID;
  DXContainerPDB() : ModulePass(ID) {}

  StringRef getPassName() const override { return "DirectX PDB Emitter"; }

  bool runOnModule(Module &M) override;

  void getAnalysisUsage(AnalysisUsage &AU) const override {
    AU.setPreservesAll();
  }

  bool shouldSkipSection(StringRef SectionName, size_t SectionSize) override;
  ArrayRef<MCDXContainerPart> collectParts() override;
};

} // namespace

bool DXContainerPDB::shouldSkipSection(StringRef SectionName,
                                       size_t SectionSize) {
  if (MCDXContainerBaseWriter::shouldSkipSection(SectionName, SectionSize))
    return true;
  if (dxil::SlimDebug && SectionName == "ILDB")
    return true;

  // Skip sections that are irrelevant for debug info.
  static const StringSet<> DebugSections{"ILDB", "ILDN", "HASH", "PDBI",
                                         "SRCI", "STAT", "RDAT", "VERS"};
  return !DebugSections.contains(SectionName);
}

static StringRef getGlobalData(const GlobalVariable &GV) {
  if (GV.hasInitializer())
    if (const auto *Data =
            dyn_cast<ConstantDataSequential>(GV.getInitializer()))
      return Data->getRawDataValues();
  return {};
}

ArrayRef<MCDXContainerPart> DXContainerPDB::collectParts() {
  Parts.clear();
  for (const GlobalVariable &GV : M->globals()) {
    StringRef Name = GV.getSection();
    StringRef Data = getGlobalData(GV);

    if (Data.empty())
      continue;
    if (shouldSkipSection(Name, Data.size()))
      continue;

    Parts.push_back({Name, Data});
  }
  return Parts;
}

static GlobalVariable *createPrivateDataGlobal(Module &M, StringRef Data) {
  Constant *Content =
      ConstantDataArray::getString(M.getContext(), Data, /*AddNull*/ false);
  auto *GV =
      new GlobalVariable(M, Content->getType(), true,
                         GlobalValue::PrivateLinkage, Content, "dx.priv");
  GV->setSection("PRIV");
  GV->setAlignment(Align(1));
  return GV;
}

bool DXContainerPDB::runOnModule(Module &M) {
  llvm::scope_exit Cleanup([&]() { reset(); });
  this->M = &M;

  SmallString<128> DebugFileName;
  ArrayRef<char> ModuleHash;
  for (const GlobalVariable &GV : M.globals()) {
    if (GV.getSection() == PdbFileNameSectionName) {
      assert(DebugFileName.empty() && "Duplicate PDBNAME section");
      DebugFileName = getGlobalData(GV);
    } else if (GV.getSection() == ModuleHashSectionName) {
      assert(ModuleHash.empty() && "Duplicate PBDHASH section");
      StringRef Data = getGlobalData(GV);
      ModuleHash = ArrayRef(Data.data(), Data.size());
    }
  }

  // PDB emission was not requested.
  if (DebugFileName.empty() && !dxil::PdbInPrivate)
    return false;
  if (ModuleHash.empty())
    report_fatal_error("Module hash for PDB not found");

  bool DeleteAfterRead = false;
  if (DebugFileName.empty()) {
    if (std::error_code EC =
            sys::fs::createTemporaryFile("dxil", "pdb", DebugFileName))
      reportFatalInternalError("Failed to create temporary PDB file");
    DeleteAfterRead = true;
  }
  llvm::scope_exit FileCleanup([&]() {
    if (DeleteAfterRead)
      sys::fs::remove(DebugFileName);
  });

  BumpPtrAllocator Allocator;
  pdb::PDBFileBuilder Builder(Allocator);

  // DirectXShaderCompiler uses block size 512.
  if (Error Err = Builder.initialize(512))
    reportFatalInternalError(std::move(Err));

  // Reserved streams that should be empty.
  static_assert(pdb::kSpecialStreamCount == 5 &&
                "First 5 streams should be empty in DirectX PDB file");
  for (uint32_t I = 0; I < pdb::kSpecialStreamCount; ++I) {
    if (auto Err = Builder.getMsfBuilder().addStream(0).takeError())
      reportFatalInternalError(std::move(Err));
  }

  // Add DXContainer stream.
  if (auto Err = Builder.getMsfBuilder().addStream(0).takeError())
    reportFatalInternalError(std::move(Err));

  // InfoStream must be filled. Bitcode hash from HASH part is used for PDB
  // GUID.
  codeview::GUID PdbGuid;
  assert(ModuleHash.size() == std::size(PdbGuid.Guid) &&
         "Module hash length must be match GUID length");
  std::copy_n(ModuleHash.begin(), std::size(PdbGuid.Guid), PdbGuid.Guid);

  auto &InfoBuilder = Builder.getInfoBuilder();
  InfoBuilder.setAge(1);
  InfoBuilder.setGuid(PdbGuid);
  InfoBuilder.setSignature(0);
  InfoBuilder.setVersion(pdb::PdbRaw_ImplVer::PdbImplVC70);

  // Write DXContainer.
  raw_svector_ostream OS(*Builder.getDXContainerData());
  write(OS, M.getTargetTriple());

  // Write PDB file.
  codeview::GUID IgnoredOutGuid;
  {
    // FIXME(sandboxing): Remove this by routing output through OutputBackend.
    auto BypassSandbox = sys::sandbox::scopedDisable();
    if (Error Err = Builder.commit(DebugFileName, &IgnoredOutGuid))
      reportFatalUsageError("Couldn't write to PDB file: " +
                            Twine(toString(std::move(Err))));
  }

  if (!dxil::PdbInPrivate)
    return false;

  ErrorOr<std::unique_ptr<MemoryBuffer>> Buf =
      M.getContext().getVirtualFileSystem().getBufferForFile(
          DebugFileName, /*FileSize=*/-1, /*RequiresNullTerminator=*/false,
          /*IsVolatile=*/false, /*IsText=*/false);
  if (!Buf)
    reportFatalInternalError("Failed to read PDB for PRIV embedding");

  appendToCompilerUsed(M, createPrivateDataGlobal(M, (*Buf)->getBuffer()));

  return true;
}

char DXContainerPDB::ID = 0;
INITIALIZE_PASS(DXContainerPDB, "dxil-pdb", "DirectX PDB Emitter", false, true)

ModulePass *llvm::createDXContainerPDBPass() { return new DXContainerPDB(); }
