//===-- ObjectContainerMachOFileset.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 "ObjectContainerMachOFileset.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleSpec.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Target/Target.h"
#include "lldb/Utility/ArchSpec.h"
#include "lldb/Utility/DataBuffer.h"
#include "lldb/Utility/Stream.h"
#include <optional>

using namespace lldb;
using namespace lldb_private;
using namespace llvm::MachO;

LLDB_PLUGIN_DEFINE(ObjectContainerMachOFileset)

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

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

ObjectContainerMachOFileset::ObjectContainerMachOFileset(
    const lldb::ModuleSP &module_sp, lldb::DataBufferSP &data_sp,
    lldb::offset_t data_offset, const lldb_private::FileSpec *file,
    lldb::offset_t offset, lldb::offset_t length)
    : ObjectContainer(module_sp, file, offset, length, data_sp, data_offset),
      m_memory_addr(LLDB_INVALID_ADDRESS) {}

ObjectContainerMachOFileset::ObjectContainerMachOFileset(
    const lldb::ModuleSP &module_sp, lldb::WritableDataBufferSP data_sp,
    const lldb::ProcessSP &process_sp, lldb::addr_t header_addr)
    : ObjectContainer(module_sp, nullptr, 0, data_sp->GetByteSize(), data_sp,
                      0),
      m_process_wp(process_sp), m_memory_addr(header_addr) {}

ObjectContainer *ObjectContainerMachOFileset::CreateInstance(
    const lldb::ModuleSP &module_sp, DataBufferSP &data_sp,
    lldb::offset_t data_offset, const FileSpec *file,
    lldb::offset_t file_offset, lldb::offset_t length) {
  if (!data_sp)
    return {};

  DataExtractor data;
  data.SetData(data_sp, data_offset, length);
  if (!MagicBytesMatch(data))
    return {};

  auto container_up = std::make_unique<ObjectContainerMachOFileset>(
      module_sp, data_sp, data_offset, file, file_offset, length);
  if (!container_up->ParseHeader())
    return {};

  return container_up.release();
}

ObjectContainer *ObjectContainerMachOFileset::CreateMemoryInstance(
    const lldb::ModuleSP &module_sp, lldb::WritableDataBufferSP data_sp,
    const lldb::ProcessSP &process_sp, lldb::addr_t header_addr) {
  if (!MagicBytesMatch(data_sp, 0, data_sp->GetByteSize()))
    return {};

  auto container_up = std::make_unique<ObjectContainerMachOFileset>(
      module_sp, data_sp, process_sp, header_addr);
  if (!container_up->ParseHeader())
    return {};

  return container_up.release();
}

ObjectContainerMachOFileset::~ObjectContainerMachOFileset() = default;

static uint32_t MachHeaderSizeFromMagic(uint32_t magic) {
  switch (magic) {
  case MH_MAGIC:
  case MH_CIGAM:
    return sizeof(struct mach_header);
  case MH_MAGIC_64:
  case MH_CIGAM_64:
    return sizeof(struct mach_header_64);
  default:
    return 0;
  }
}

static std::optional<mach_header> ParseMachOHeader(DataExtractor &data) {
  lldb::offset_t offset = 0;
  mach_header header;
  header.magic = data.GetU32(&offset);
  switch (header.magic) {
  case MH_MAGIC:
    data.SetByteOrder(endian::InlHostByteOrder());
    data.SetAddressByteSize(4);
    break;
  case MH_MAGIC_64:
    data.SetByteOrder(endian::InlHostByteOrder());
    data.SetAddressByteSize(8);
    break;
  case MH_CIGAM:
    data.SetByteOrder(endian::InlHostByteOrder() == eByteOrderBig
                          ? eByteOrderLittle
                          : eByteOrderBig);
    data.SetAddressByteSize(4);
    break;
  case MH_CIGAM_64:
    data.SetByteOrder(endian::InlHostByteOrder() == eByteOrderBig
                          ? eByteOrderLittle
                          : eByteOrderBig);
    data.SetAddressByteSize(8);
    break;
  default:
    return {};
  }

  header.cputype = data.GetU32(&offset);
  header.cpusubtype = data.GetU32(&offset);
  header.filetype = data.GetU32(&offset);
  header.ncmds = data.GetU32(&offset);
  header.sizeofcmds = data.GetU32(&offset);
  return header;
}

static bool
ParseFileset(DataExtractor &data, mach_header header,
             std::vector<ObjectContainerMachOFileset::Entry> &entries,
             std::optional<lldb::addr_t> load_addr = std::nullopt) {
  lldb::offset_t offset = MachHeaderSizeFromMagic(header.magic);
  lldb::offset_t slide = 0;
  for (uint32_t i = 0; i < header.ncmds; ++i) {
    const lldb::offset_t load_cmd_offset = offset;
    load_command lc = {};
    if (data.GetU32(&offset, &lc.cmd, 2) == nullptr)
      break;

    // If we know the load address we can compute the slide.
    if (load_addr) {
      if (lc.cmd == llvm::MachO::LC_SEGMENT_64) {
        segment_command_64 segment;
        data.CopyData(load_cmd_offset, sizeof(segment_command_64), &segment);
        if (llvm::StringRef(segment.segname) == "__TEXT")
          slide = *load_addr - segment.vmaddr;
      }
    }

    if (lc.cmd == LC_FILESET_ENTRY) {
      fileset_entry_command entry;
      data.CopyData(load_cmd_offset, sizeof(fileset_entry_command), &entry);
      lldb::offset_t entry_id_offset = load_cmd_offset + entry.entry_id.offset;
      const char *id = data.GetCStr(&entry_id_offset);
      entries.emplace_back(entry.vmaddr + slide, entry.fileoff,
                           std::string(id));
    }

    offset = load_cmd_offset + lc.cmdsize;
  }

  return true;
}

bool ObjectContainerMachOFileset::ParseHeader(
    DataExtractor &data, const lldb_private::FileSpec &file,
    lldb::offset_t file_offset, std::vector<Entry> &entries) {
  std::optional<mach_header> header = ParseMachOHeader(data);

  if (!header)
    return false;

  const size_t header_size = MachHeaderSizeFromMagic(header->magic);
  const size_t header_and_lc_size = header_size + header->sizeofcmds;

  if (data.GetByteSize() < header_and_lc_size) {
    DataBufferSP data_sp =
        ObjectFile::MapFileData(file, header_and_lc_size, file_offset);
    data.SetData(data_sp);
  }

  return ParseFileset(data, *header, entries);
}

bool ObjectContainerMachOFileset::ParseHeader() {
  ModuleSP module_sp(GetModule());
  if (!module_sp)
    return false;

  std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());

  std::optional<mach_header> header = ParseMachOHeader(m_data);
  if (!header)
    return false;

  const size_t header_size = MachHeaderSizeFromMagic(header->magic);
  const size_t header_and_lc_size = header_size + header->sizeofcmds;

  if (m_data.GetByteSize() < header_and_lc_size) {
    ProcessSP process_sp(m_process_wp.lock());
    DataBufferSP data_sp =
        process_sp
            ? ObjectFile::ReadMemory(process_sp, m_memory_addr,
                                     header_and_lc_size)
            : ObjectFile::MapFileData(m_file, header_and_lc_size, m_offset);
    m_data.SetData(data_sp);
  }

  return ParseFileset(m_data, *header, m_entries, m_memory_addr);
}

size_t ObjectContainerMachOFileset::GetModuleSpecifications(
    const lldb_private::FileSpec &file, lldb::DataBufferSP &data_sp,
    lldb::offset_t data_offset, lldb::offset_t file_offset,
    lldb::offset_t file_size, lldb_private::ModuleSpecList &specs) {
  const size_t initial_count = specs.GetSize();

  DataExtractor data;
  data.SetData(data_sp, data_offset, data_sp->GetByteSize());

  if (MagicBytesMatch(data)) {
    std::vector<Entry> entries;
    if (ParseHeader(data, file, file_offset, entries)) {
      for (const Entry &entry : entries) {
        const lldb::offset_t entry_offset = entry.fileoff + file_offset;
        if (ObjectFile::GetModuleSpecifications(
                file, entry_offset, file_size - entry_offset, specs)) {
          ModuleSpec &spec = specs.GetModuleSpecRefAtIndex(specs.GetSize() - 1);
          spec.GetObjectName() = ConstString(entry.id);
        }
      }
    }
  }
  return specs.GetSize() - initial_count;
}

bool ObjectContainerMachOFileset::MagicBytesMatch(DataBufferSP data_sp,
                                                  lldb::addr_t data_offset,
                                                  lldb::addr_t data_length) {
  DataExtractor data;
  data.SetData(data_sp, data_offset, data_length);
  return MagicBytesMatch(data);
}

bool ObjectContainerMachOFileset::MagicBytesMatch(const DataExtractor &data) {
  lldb::offset_t offset = 0;
  uint32_t magic = data.GetU32(&offset);
  switch (magic) {
  case MH_MAGIC:
  case MH_CIGAM:
  case MH_MAGIC_64:
  case MH_CIGAM_64:
    break;
  default:
    return false;
  }
  offset += 4; // cputype
  offset += 4; // cpusubtype
  uint32_t filetype = data.GetU32(&offset);
  return filetype == MH_FILESET;
}

ObjectFileSP
ObjectContainerMachOFileset::GetObjectFile(const lldb_private::FileSpec *file) {
  ModuleSP module_sp(GetModule());
  if (!module_sp)
    return {};

  ConstString object_name = module_sp->GetObjectName();
  if (!object_name)
    return {};

  Entry *entry = FindEntry(object_name.GetCString());
  if (!entry)
    return {};

  DataBufferSP data_sp;
  lldb::offset_t data_offset = 0;
  return ObjectFile::FindPlugin(module_sp, file, m_offset + entry->fileoff,
                                m_data.GetByteSize() - entry->fileoff, data_sp,
                                data_offset);
}

ObjectContainerMachOFileset::Entry *
ObjectContainerMachOFileset::FindEntry(llvm::StringRef id) {
  for (Entry &entry : m_entries) {
    if (entry.id == id)
      return &entry;
  }
  return nullptr;
}
