//===- DXILContainerPDB.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/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/Analysis.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/PassManager.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 DXILContainerPDBImpl : MCDXContainerBaseWriter {
  Module *M = nullptr;
  SmallVector<MCDXContainerPart> Parts;

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

public:
  bool shouldSkipSection(StringRef SectionName, size_t SectionSize) override;
  ArrayRef<MCDXContainerPart> collectParts() override;
  bool runOnModule(Module &M);
};

class DXILContainerPDBLegacy : public ModulePass {
public:
  static char ID;
  DXILContainerPDBLegacy() : ModulePass(ID) {}

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

  bool runOnModule(Module &M) override;

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

} // namespace

bool DXILContainerPDBImpl::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> DXILContainerPDBImpl::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 DXILContainerPDBImpl::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 DXILContainerPDBLegacy::ID = 0;
INITIALIZE_PASS(DXILContainerPDBLegacy, "dxil-container-pdb",
                "DirectX PDB Emitter", false, true)

ModulePass *llvm::createDXILContainerPDBLegacyPass() {
  return new DXILContainerPDBLegacy();
}

bool DXILContainerPDBLegacy::runOnModule(Module &M) {
  DXILContainerPDBImpl Impl;
  return Impl.runOnModule(M);
}

PreservedAnalyses DXILContainerPDBPass::run(Module &M,
                                            ModuleAnalysisManager &MAM) {
  DXILContainerPDBImpl Impl;
  Impl.runOnModule(M);
  return PreservedAnalyses::all();
}
