//===- 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 "lld/Common/Memory.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

TpiSource::TpiSource(TpiKind k, const ObjFile *f) : kind(k), file(f) {}

TpiSource *makeTpiSource(const ObjFile *f) {
  return make<TpiSource>(TpiSource::Regular, f);
}

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

TpiSource *makePrecompSource(const ObjFile *f) {
  return make<PrecompSource>(f);
}

TpiSource *makeUsePrecompSource(const ObjFile *f,
                                           const PrecompRecord *precomp) {
  return make<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 make<TypeServerSource>(m, session.release());
}

} // namespace coff
} // namespace lld
