//===-- ObjectFilePDB.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 "ObjectFilePDB.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleSpec.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/Section.h"
#include "lldb/Utility/StreamString.h"
#include "llvm/BinaryFormat/Magic.h"
#include "llvm/DebugInfo/PDB/Native/DbiStream.h"
#include "llvm/DebugInfo/PDB/Native/InfoStream.h"
#include "llvm/DebugInfo/PDB/Native/NativeSession.h"
#include "llvm/DebugInfo/PDB/Native/PDBFile.h"
#include "llvm/DebugInfo/PDB/PDB.h"
#include "llvm/Support/BinaryByteStream.h"

using namespace lldb;
using namespace lldb_private;
using namespace llvm::pdb;
using namespace llvm::codeview;

LLDB_PLUGIN_DEFINE(ObjectFilePDB)

static UUID GetPDBUUID(InfoStream &IS, DbiStream &DS) {
  UUID::CvRecordPdb70 debug_info;
  memcpy(&debug_info.Uuid, IS.getGuid().Guid, sizeof(debug_info.Uuid));
  debug_info.Age = DS.getAge();
  return UUID(debug_info);
}

char ObjectFilePDB::ID;

void ObjectFilePDB::Initialize() {
  PluginManager::RegisterPlugin(GetPluginNameStatic(),
                                GetPluginDescriptionStatic(), CreateInstance,
                                CreateMemoryInstance, GetModuleSpecifications);
}

void ObjectFilePDB::Terminate() {
  PluginManager::UnregisterPlugin(CreateInstance);
}

ArchSpec ObjectFilePDB::GetArchitecture() {
  auto dbi_stream = m_file_up->getPDBDbiStream();
  if (!dbi_stream) {
    llvm::consumeError(dbi_stream.takeError());
    return ArchSpec();
  }

  PDB_Machine machine = dbi_stream->getMachineType();
  switch (machine) {
  default:
    break;
  case PDB_Machine::Amd64:
  case PDB_Machine::x86:
  case PDB_Machine::PowerPC:
  case PDB_Machine::PowerPCFP:
  case PDB_Machine::Arm:
  case PDB_Machine::ArmNT:
  case PDB_Machine::Thumb:
  case PDB_Machine::Arm64:
    ArchSpec arch;
    arch.SetArchitecture(eArchTypeCOFF, static_cast<int>(machine),
                         LLDB_INVALID_CPUTYPE);
    return arch;
  }
  return ArchSpec();
}

bool ObjectFilePDB::initPDBFile() {
  m_file_up = loadPDBFile(m_file.GetPath(), m_allocator);
  if (!m_file_up)
    return false;
  auto info_stream = m_file_up->getPDBInfoStream();
  if (!info_stream) {
    llvm::consumeError(info_stream.takeError());
    return false;
  }
  auto dbi_stream = m_file_up->getPDBDbiStream();
  if (!dbi_stream) {
    llvm::consumeError(dbi_stream.takeError());
    return false;
  }
  m_uuid = GetPDBUUID(*info_stream, *dbi_stream);
  return true;
}

ObjectFile *ObjectFilePDB::CreateInstance(const ModuleSP &module_sp,
                                          DataExtractorSP extractor_sp,
                                          offset_t data_offset,
                                          const FileSpec *file,
                                          offset_t file_offset,
                                          offset_t length) {
  auto objfile_up = std::make_unique<ObjectFilePDB>(
      module_sp, extractor_sp, data_offset, file, file_offset, length);
  if (!objfile_up->initPDBFile())
    return nullptr;
  return objfile_up.release();
}

ObjectFile *ObjectFilePDB::CreateMemoryInstance(const ModuleSP &module_sp,
                                                WritableDataBufferSP data_sp,
                                                const ProcessSP &process_sp,
                                                addr_t header_addr) {
  return nullptr;
}

ModuleSpecList
ObjectFilePDB::GetModuleSpecifications(const FileSpec &file,
                                       DataExtractorSP &extractor_sp,
                                       offset_t file_offset, offset_t length) {
  ModuleSpec module_spec(file);
  llvm::BumpPtrAllocator allocator;
  std::unique_ptr<PDBFile> pdb_file = loadPDBFile(file.GetPath(), allocator);
  if (!pdb_file)
    return {};

  auto info_stream = pdb_file->getPDBInfoStream();
  if (!info_stream) {
    llvm::consumeError(info_stream.takeError());
    return {};
  }
  auto dbi_stream = pdb_file->getPDBDbiStream();
  if (!dbi_stream) {
    llvm::consumeError(dbi_stream.takeError());
    return {};
  }

  lldb_private::UUID &uuid = module_spec.GetUUID();
  uuid = GetPDBUUID(*info_stream, *dbi_stream);

  ModuleSpecList specs;
  ArchSpec &module_arch = module_spec.GetArchitecture();
  switch (dbi_stream->getMachineType()) {
  case PDB_Machine::Amd64:
    module_arch.SetTriple("x86_64-pc-windows");
    specs.Append(module_spec);
    break;
  case PDB_Machine::x86:
    module_arch.SetTriple("i386-pc-windows");
    specs.Append(module_spec);
    break;
  case PDB_Machine::ArmNT:
    module_arch.SetTriple("armv7-pc-windows");
    specs.Append(module_spec);
    break;
  case PDB_Machine::Arm64:
    module_arch.SetTriple("aarch64-pc-windows");
    specs.Append(module_spec);
    break;
  default:
    break;
  }

  return specs;
}

ObjectFilePDB::ObjectFilePDB(const ModuleSP &module_sp,
                             DataExtractorSP &extractor_sp,
                             offset_t data_offset, const FileSpec *file,
                             offset_t offset, offset_t length)
    : ObjectFile(module_sp, file, offset, length, extractor_sp, data_offset) {}

std::unique_ptr<PDBFile>
ObjectFilePDB::loadPDBFile(std::string PdbPath,
                           llvm::BumpPtrAllocator &Allocator) {
  llvm::file_magic magic;
  auto ec = llvm::identify_magic(PdbPath, magic);
  if (ec || magic != llvm::file_magic::pdb)
    return nullptr;
  llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> ErrorOrBuffer =
      llvm::MemoryBuffer::getFile(PdbPath, /*IsText=*/false,
                                  /*RequiresNullTerminator=*/false);
  if (!ErrorOrBuffer)
    return nullptr;
  std::unique_ptr<llvm::MemoryBuffer> Buffer = std::move(*ErrorOrBuffer);

  llvm::StringRef Path = Buffer->getBufferIdentifier();
  auto Stream = std::make_unique<llvm::MemoryBufferByteStream>(
      std::move(Buffer), llvm::endianness::little);

  auto File = std::make_unique<PDBFile>(Path, std::move(Stream), Allocator);
  if (auto EC = File->parseFileHeaders()) {
    llvm::consumeError(std::move(EC));
    return nullptr;
  }
  if (auto EC = File->parseStreamData()) {
    llvm::consumeError(std::move(EC));
    return nullptr;
  }

  return File;
}
