//===- DebugTypes.cpp -----------------------------------------------------===//
//
// 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 "DebugTypes.h"
#include "Driver.h"
#include "InputFiles.h"
#include "lld/Common/ErrorHandler.h"
#include "llvm/DebugInfo/CodeView/TypeRecord.h"
#include "llvm/DebugInfo/PDB/GenericError.h"
#include "llvm/DebugInfo/PDB/Native/InfoStream.h"
#include "llvm/DebugInfo/PDB/Native/NativeSession.h"
#include "llvm/DebugInfo/PDB/Native/PDBFile.h"
#include "llvm/Support/Path.h"

using namespace llvm;
using namespace llvm::codeview;

namespace lld {
namespace coff {

namespace {
// The TypeServerSource class represents a PDB type server, a file referenced by
// OBJ files compiled with MSVC /Zi. A single PDB can be shared by several OBJ
// files, therefore there must be only once instance per OBJ lot. The file path
// is discovered from the dependent OBJ's debug type stream. The
// TypeServerSource object is then queued and loaded by the COFF Driver. The
// debug type stream for such PDB files will be merged first in the final PDB,
// before any dependent OBJ.
class TypeServerSource : public TpiSource {
public:
  explicit TypeServerSource(MemoryBufferRef m, llvm::pdb::NativeSession *s)
      : TpiSource(PDB, nullptr), session(s), mb(m) {}

  // Queue a PDB type server for loading in the COFF Driver
  static void enqueue(const ObjFile *dependentFile,
                      const TypeServer2Record &ts);

  // Create an instance
  static Expected<TypeServerSource *> getInstance(MemoryBufferRef m);

  // Fetch the PDB instance loaded for a corresponding dependent OBJ.
  static Expected<TypeServerSource *>
  findFromFile(const ObjFile *dependentFile);

  static std::map<std::string, std::pair<std::string, TypeServerSource *>>
      instances;

  // The interface to the PDB (if it was opened successfully)
  std::unique_ptr<llvm::pdb::NativeSession> session;

private:
  MemoryBufferRef mb;
};

// This class represents the debug type stream of an OBJ file that depends on a
// PDB type server (see TypeServerSource).
class UseTypeServerSource : public TpiSource {
public:
  UseTypeServerSource(const ObjFile *f, const TypeServer2Record *ts)
      : TpiSource(UsingPDB, f), typeServerDependency(*ts) {}

  // Information about the PDB type server dependency, that needs to be loaded
  // in before merging this OBJ.
  TypeServer2Record typeServerDependency;
};

// This class represents the debug type stream of a Microsoft precompiled
// headers OBJ (PCH OBJ). This OBJ kind needs to be merged first in the output
// PDB, before any other OBJs that depend on this. Note that only MSVC generate
// such files, clang does not.
class PrecompSource : public TpiSource {
public:
  PrecompSource(const ObjFile *f) : TpiSource(PCH, f) {}
};

// This class represents the debug type stream of an OBJ file that depends on a
// Microsoft precompiled headers OBJ (see PrecompSource).
class UsePrecompSource : public TpiSource {
public:
  UsePrecompSource(const ObjFile *f, const PrecompRecord *precomp)
      : TpiSource(UsingPCH, f), precompDependency(*precomp) {}

  // Information about the Precomp OBJ dependency, that needs to be loaded in
  // before merging this OBJ.
  PrecompRecord precompDependency;
};
} // namespace

static std::vector<std::unique_ptr<TpiSource>> GC;

TpiSource::TpiSource(TpiKind k, const ObjFile *f) : kind(k), file(f) {
  GC.push_back(std::unique_ptr<TpiSource>(this));
}

TpiSource *makeTpiSource(const ObjFile *f) {
  return new TpiSource(TpiSource::Regular, f);
}

TpiSource *makeUseTypeServerSource(const ObjFile *f,
                                              const TypeServer2Record *ts) {
  TypeServerSource::enqueue(f, *ts);
  return new UseTypeServerSource(f, ts);
}

TpiSource *makePrecompSource(const ObjFile *f) {
  return new PrecompSource(f);
}

TpiSource *makeUsePrecompSource(const ObjFile *f,
                                           const PrecompRecord *precomp) {
  return new UsePrecompSource(f, precomp);
}

template <>
const PrecompRecord &retrieveDependencyInfo(const TpiSource *source) {
  assert(source->kind == TpiSource::UsingPCH);
  return ((const UsePrecompSource *)source)->precompDependency;
}

template <>
const TypeServer2Record &retrieveDependencyInfo(const TpiSource *source) {
  assert(source->kind == TpiSource::UsingPDB);
  return ((const UseTypeServerSource *)source)->typeServerDependency;
}

std::map<std::string, std::pair<std::string, TypeServerSource *>>
    TypeServerSource::instances;

// Make a PDB path assuming the PDB is in the same folder as the OBJ
static std::string getPdbBaseName(const ObjFile *file, StringRef tSPath) {
  StringRef localPath =
      !file->parentName.empty() ? file->parentName : file->getName();
  SmallString<128> path = sys::path::parent_path(localPath);

  // Currently, type server PDBs are only created by MSVC cl, which only runs
  // on Windows, so we can assume type server paths are Windows style.
  sys::path::append(path, sys::path::filename(tSPath, sys::path::Style::windows));
  return path.str();
}

// The casing of the PDB path stamped in the OBJ can differ from the actual path
// on disk. With this, we ensure to always use lowercase as a key for the
// PDBInputFile::Instances map, at least on Windows.
static std::string normalizePdbPath(StringRef path) {
#if defined(_WIN32)
  return path.lower();
#else // LINUX
  return path;
#endif
}

// If existing, return the actual PDB path on disk.
static Optional<std::string> findPdbPath(StringRef pdbPath,
                                         const ObjFile *dependentFile) {
  // Ensure the file exists before anything else. In some cases, if the path
  // points to a removable device, Driver::enqueuePath() would fail with an
  // error (EAGAIN, "resource unavailable try again") which we want to skip
  // silently.
  if (llvm::sys::fs::exists(pdbPath))
    return normalizePdbPath(pdbPath);
  std::string ret = getPdbBaseName(dependentFile, pdbPath);
  if (llvm::sys::fs::exists(ret))
    return normalizePdbPath(ret);
  return None;
}

// Fetch the PDB instance that was already loaded by the COFF Driver.
Expected<TypeServerSource *>
TypeServerSource::findFromFile(const ObjFile *dependentFile) {
  const TypeServer2Record &ts =
      retrieveDependencyInfo<TypeServer2Record>(dependentFile->debugTypesObj);

  Optional<std::string> p = findPdbPath(ts.Name, dependentFile);
  if (!p)
    return createFileError(ts.Name, errorCodeToError(std::error_code(
                                        ENOENT, std::generic_category())));

  auto it = TypeServerSource::instances.find(*p);
  // The PDB file exists on disk, at this point we expect it to have been
  // inserted in the map by TypeServerSource::loadPDB()
  assert(it != TypeServerSource::instances.end());

  std::pair<std::string, TypeServerSource *> &pdb = it->second;

  if (!pdb.second)
    return createFileError(
        *p, createStringError(inconvertibleErrorCode(), pdb.first.c_str()));

  pdb::PDBFile &pdbFile = (pdb.second)->session->getPDBFile();
  pdb::InfoStream &info = cantFail(pdbFile.getPDBInfoStream());

  // Just because a file with a matching name was found doesn't mean it can be
  // used. The GUID must match between the PDB header and the OBJ
  // TypeServer2 record. The 'Age' is used by MSVC incremental compilation.
  if (info.getGuid() != ts.getGuid())
    return createFileError(
        ts.Name,
        make_error<pdb::PDBError>(pdb::pdb_error_code::signature_out_of_date));

  return pdb.second;
}

// FIXME: Temporary interface until PDBLinker::maybeMergeTypeServerPDB() is
// moved here.
Expected<llvm::pdb::NativeSession *> findTypeServerSource(const ObjFile *f) {
  Expected<TypeServerSource *> ts = TypeServerSource::findFromFile(f);
  if (!ts)
    return ts.takeError();
  return ts.get()->session.get();
}

// Queue a PDB type server for loading in the COFF Driver
void TypeServerSource::enqueue(const ObjFile *dependentFile,
                               const TypeServer2Record &ts) {
  // Start by finding where the PDB is located (either the record path or next
  // to the OBJ file)
  Optional<std::string> p = findPdbPath(ts.Name, dependentFile);
  if (!p)
    return;
  auto it = TypeServerSource::instances.emplace(
      *p, std::pair<std::string, TypeServerSource *>{});
  if (!it.second)
    return; // another OBJ already scheduled this PDB for load

  driver->enqueuePath(*p, false, false);
}

// Create an instance of TypeServerSource or an error string if the PDB couldn't
// be loaded. The error message will be displayed later, when the referring OBJ
// will be merged in. NOTE - a PDB load failure is not a link error: some
// debug info will simply be missing from the final PDB - that is the default
// accepted behavior.
void loadTypeServerSource(llvm::MemoryBufferRef m) {
  std::string path = normalizePdbPath(m.getBufferIdentifier());

  Expected<TypeServerSource *> ts = TypeServerSource::getInstance(m);
  if (!ts)
    TypeServerSource::instances[path] = {toString(ts.takeError()), nullptr};
  else
    TypeServerSource::instances[path] = {{}, *ts};
}

Expected<TypeServerSource *> TypeServerSource::getInstance(MemoryBufferRef m) {
  std::unique_ptr<llvm::pdb::IPDBSession> iSession;
  Error err = pdb::NativeSession::createFromPdb(
      MemoryBuffer::getMemBuffer(m, false), iSession);
  if (err)
    return std::move(err);

  std::unique_ptr<llvm::pdb::NativeSession> session(
      static_cast<pdb::NativeSession *>(iSession.release()));

  pdb::PDBFile &pdbFile = session->getPDBFile();
  Expected<pdb::InfoStream &> info = pdbFile.getPDBInfoStream();
  // All PDB Files should have an Info stream.
  if (!info)
    return info.takeError();
  return new TypeServerSource(m, session.release());
}

} // namespace coff
} // namespace lld
