//===-- DynamicLoaderDarwinKernel.h -----------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#ifndef liblldb_DynamicLoaderDarwinKernel_h_
#define liblldb_DynamicLoaderDarwinKernel_h_

// C Includes
// C++ Includes
#include <mutex>
#include <string>
#include <vector>

// Other libraries and framework includes

#include "lldb/Utility/SafeMachO.h"

// Project includes
#include "lldb/Target/DynamicLoader.h"
#include "lldb/Target/Process.h"
#include "lldb/Utility/FileSpec.h"
#include "lldb/Utility/UUID.h"

class DynamicLoaderDarwinKernel : public lldb_private::DynamicLoader {
public:
  DynamicLoaderDarwinKernel(lldb_private::Process *process,
                            lldb::addr_t kernel_addr);

  ~DynamicLoaderDarwinKernel() override;

  //------------------------------------------------------------------
  // Static Functions
  //------------------------------------------------------------------
  static void Initialize();

  static void Terminate();

  static lldb_private::ConstString GetPluginNameStatic();

  static const char *GetPluginDescriptionStatic();

  static lldb_private::DynamicLoader *
  CreateInstance(lldb_private::Process *process, bool force);

  static void DebuggerInitialize(lldb_private::Debugger &debugger);

  static lldb::addr_t SearchForDarwinKernel(lldb_private::Process *process);

  //------------------------------------------------------------------
  /// Called after attaching a process.
  ///
  /// Allow DynamicLoader plug-ins to execute some code after
  /// attaching to a process.
  //------------------------------------------------------------------
  void DidAttach() override;

  void DidLaunch() override;

  lldb::ThreadPlanSP GetStepThroughTrampolinePlan(lldb_private::Thread &thread,
                                                  bool stop_others) override;

  lldb_private::Status CanLoadImage() override;

  //------------------------------------------------------------------
  // PluginInterface protocol
  //------------------------------------------------------------------
  lldb_private::ConstString GetPluginName() override;

  uint32_t GetPluginVersion() override;

protected:
  void PrivateInitialize(lldb_private::Process *process);

  void PrivateProcessStateChanged(lldb_private::Process *process,
                                  lldb::StateType state);

  void UpdateIfNeeded();

  void LoadKernelModuleIfNeeded();

  void Clear(bool clear_process);

  void PutToLog(lldb_private::Log *log) const;

  static bool
  BreakpointHitCallback(void *baton,
                        lldb_private::StoppointCallbackContext *context,
                        lldb::user_id_t break_id, lldb::user_id_t break_loc_id);

  bool BreakpointHit(lldb_private::StoppointCallbackContext *context,
                     lldb::user_id_t break_id, lldb::user_id_t break_loc_id);
  uint32_t GetAddrByteSize() { return m_kernel.GetAddressByteSize(); }

  static lldb::ByteOrder GetByteOrderFromMagic(uint32_t magic);

  enum {
    KERNEL_MODULE_MAX_NAME = 64u,
    // Versions less than 2 didn't have an entry size,
    // they had a 64 bit name, 16 byte UUID, 8 byte addr,
    // 8 byte size, 8 byte version, 4 byte load tag, and
    // 4 byte flags
    KERNEL_MODULE_ENTRY_SIZE_VERSION_1 = 64u + 16u + 8u + 8u + 8u + 4u + 4u
  };

  // class KextImageInfo represents a single kext or kernel binary image.
  // The class was designed to hold the information from the
  // OSKextLoadedKextSummary
  // structure (in libkern/libkern/OSKextLibPrivate.h from xnu).  The kernel
  // maintains
  // a list of loded kexts in memory (the OSKextLoadedKextSummaryHeader
  // structure,
  // which points to an array of OSKextLoadedKextSummary's).
  //
  // A KextImageInfos may have -
  //
  // 1. The load address, name, UUID, and size of a kext/kernel binary in memory
  //    (read straight out of the kernel's list-of-kexts loaded)
  // 2. A ModuleSP based on a MemoryModule read out of the kernel's memory
  //    (very unlikely to have any symbolic information)
  // 3. A ModuleSP for an on-disk copy of the kext binary, possibly with debug
  // info
  //    or a dSYM
  //
  // For performance reasons, the developer may prefer that lldb not load the
  // kexts out
  // of memory at the start of a kernel session.  But we should build up /
  // maintain a
  // list of kexts that the kernel has told us about so we can relocate a kext
  // module
  // later if the user explicitly adds it to the target.

  class KextImageInfo {
  public:
    KextImageInfo()
        : m_name(), m_module_sp(), m_memory_module_sp(),
          m_load_process_stop_id(UINT32_MAX), m_uuid(),
          m_load_address(LLDB_INVALID_ADDRESS), m_size(0),
          m_kernel_image(false) {}

    void Clear() {
      m_load_address = LLDB_INVALID_ADDRESS;
      m_size = 0;
      m_name.clear();
      m_uuid.Clear();
      m_module_sp.reset();
      m_memory_module_sp.reset();
      m_load_process_stop_id = UINT32_MAX;
    }

    bool LoadImageAtFileAddress(lldb_private::Process *process);

    bool LoadImageUsingMemoryModule(lldb_private::Process *process);

    bool IsLoaded() { return m_load_process_stop_id != UINT32_MAX; }

    void SetLoadAddress(
        lldb::addr_t load_addr); // Address of the Mach-O header for this binary

    lldb::addr_t
    GetLoadAddress() const; // Address of the Mach-O header for this binary

    lldb_private::UUID GetUUID() const;

    void SetUUID(const lldb_private::UUID &uuid);

    void SetName(const char *);

    std::string GetName() const;

    void SetModule(lldb::ModuleSP module);

    lldb::ModuleSP GetModule();

    // try to fill in m_memory_module_sp from memory based on the m_load_address
    bool ReadMemoryModule(lldb_private::Process *process);

    bool IsKernel()
        const; // true if this is the mach_kernel; false if this is a kext

    void SetIsKernel(bool is_kernel);

    uint64_t GetSize() const;

    void SetSize(uint64_t size);

    uint32_t
    GetProcessStopId() const; // the stop-id when this binary was first noticed

    void SetProcessStopId(uint32_t stop_id);

    bool operator==(const KextImageInfo &rhs);

    uint32_t GetAddressByteSize(); // as determined by Mach-O header

    lldb::ByteOrder GetByteOrder(); // as determined by Mach-O header

    lldb_private::ArchSpec
    GetArchitecture() const; // as determined by Mach-O header

    void PutToLog(lldb_private::Log *log) const;

    typedef std::vector<KextImageInfo> collection;
    typedef collection::iterator iterator;
    typedef collection::const_iterator const_iterator;

  private:
    std::string m_name;
    lldb::ModuleSP m_module_sp;
    lldb::ModuleSP m_memory_module_sp;
    uint32_t m_load_process_stop_id; // the stop-id when this module was added
                                     // to the Target
    lldb_private::UUID
        m_uuid; // UUID for this dylib if it has one, else all zeros
    lldb::addr_t m_load_address;
    uint64_t m_size;
    bool m_kernel_image; // true if this is the kernel, false if this is a kext
  };

  struct OSKextLoadedKextSummaryHeader {
    uint32_t version;
    uint32_t entry_size;
    uint32_t entry_count;
    lldb::addr_t image_infos_addr;

    OSKextLoadedKextSummaryHeader()
        : version(0), entry_size(0), entry_count(0),
          image_infos_addr(LLDB_INVALID_ADDRESS) {}

    uint32_t GetSize() {
      switch (version) {
      case 0:
        return 0; // Can't know the size without a valid version
      case 1:
        return 8; // Version 1 only had a version + entry_count
      default:
        break;
      }
      // Version 2 and above has version, entry_size, entry_count, and reserved
      return 16;
    }

    void Clear() {
      version = 0;
      entry_size = 0;
      entry_count = 0;
      image_infos_addr = LLDB_INVALID_ADDRESS;
    }

    bool IsValid() const { return version >= 1 || version <= 2; }
  };

  void RegisterNotificationCallbacks();

  void UnregisterNotificationCallbacks();

  void SetNotificationBreakpointIfNeeded();

  bool ReadAllKextSummaries();

  bool ReadKextSummaryHeader();

  bool ParseKextSummaries(const lldb_private::Address &kext_summary_addr,
                          uint32_t count);

  void
  UpdateImageInfosHeaderAndLoadCommands(KextImageInfo::collection &image_infos,
                                        uint32_t infos_count,
                                        bool update_executable);

  uint32_t ReadKextSummaries(const lldb_private::Address &kext_summary_addr,
                             uint32_t image_infos_count,
                             KextImageInfo::collection &image_infos);

  static lldb::addr_t
  SearchForKernelAtSameLoadAddr(lldb_private::Process *process);

  static lldb::addr_t
  SearchForKernelWithDebugHints(lldb_private::Process *process);

  static lldb::addr_t SearchForKernelNearPC(lldb_private::Process *process);

  static lldb::addr_t
  SearchForKernelViaExhaustiveSearch(lldb_private::Process *process);

  static bool
  ReadMachHeader(lldb::addr_t addr, lldb_private::Process *process, llvm::MachO::mach_header &mh);

  static lldb_private::UUID
  CheckForKernelImageAtAddress(lldb::addr_t addr,
                               lldb_private::Process *process);

  lldb::addr_t m_kernel_load_address;
  KextImageInfo m_kernel; // Info about the current kernel image being used

  lldb_private::Address m_kext_summary_header_ptr_addr;
  lldb_private::Address m_kext_summary_header_addr;
  OSKextLoadedKextSummaryHeader m_kext_summary_header;
  KextImageInfo::collection m_known_kexts;
  mutable std::recursive_mutex m_mutex;
  lldb::user_id_t m_break_id;

private:
  DISALLOW_COPY_AND_ASSIGN(DynamicLoaderDarwinKernel);
};

#endif // liblldb_DynamicLoaderDarwinKernel_h_
