//===-- RenderScriptRuntime.h -----------------------------------*- C++ -*-===//
//
// 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
//
//===----------------------------------------------------------------------===//

#ifndef LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_RENDERSCRIPT_RENDERSCRIPTRUNTIME_RENDERSCRIPTRUNTIME_H
#define LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_RENDERSCRIPT_RENDERSCRIPTRUNTIME_RENDERSCRIPTRUNTIME_H

#include <array>
#include <map>
#include <memory>
#include <string>
#include <vector>

#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include "lldb/Core/Module.h"
#include "lldb/Expression/LLVMUserExpression.h"
#include "lldb/Target/LanguageRuntime.h"
#include "lldb/lldb-private.h"

#include "Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.h"

namespace clang {
class TargetOptions;
}

namespace lldb_private {
namespace lldb_renderscript {

typedef uint32_t RSSlot;
class RSModuleDescriptor;
struct RSGlobalDescriptor;
struct RSKernelDescriptor;
struct RSReductionDescriptor;
struct RSScriptGroupDescriptor;

typedef std::shared_ptr<RSModuleDescriptor> RSModuleDescriptorSP;
typedef std::shared_ptr<RSGlobalDescriptor> RSGlobalDescriptorSP;
typedef std::shared_ptr<RSKernelDescriptor> RSKernelDescriptorSP;
typedef std::shared_ptr<RSScriptGroupDescriptor> RSScriptGroupDescriptorSP;

struct RSCoordinate {
  uint32_t x = 0, y = 0, z = 0;

  RSCoordinate() = default;

  bool operator==(const lldb_renderscript::RSCoordinate &rhs) {
    return x == rhs.x && y == rhs.y && z == rhs.z;
  }
};

// Breakpoint Resolvers decide where a breakpoint is placed, so having our own
// allows us to limit the search scope to RS kernel modules. As well as check
// for .expand kernels as a fallback.
class RSBreakpointResolver : public BreakpointResolver {
public:
  RSBreakpointResolver(const lldb::BreakpointSP &bp, ConstString name)
      : BreakpointResolver(bp, BreakpointResolver::NameResolver),
        m_kernel_name(name) {}

  void GetDescription(Stream *strm) override {
    if (strm)
      strm->Printf("RenderScript kernel breakpoint for '%s'",
                   m_kernel_name.AsCString());
  }

  void Dump(Stream *s) const override {}

  Searcher::CallbackReturn SearchCallback(SearchFilter &filter,
                                          SymbolContext &context,
                                          Address *addr) override;

  lldb::SearchDepth GetDepth() override { return lldb::eSearchDepthModule; }

  lldb::BreakpointResolverSP
  CopyForBreakpoint(lldb::BreakpointSP &breakpoint) override {
    lldb::BreakpointResolverSP ret_sp(
        new RSBreakpointResolver(breakpoint, m_kernel_name));
    return ret_sp;
  }

protected:
  ConstString m_kernel_name;
};

class RSReduceBreakpointResolver : public BreakpointResolver {
public:
  enum ReduceKernelTypeFlags {
    eKernelTypeAll = ~(0),
    eKernelTypeNone = 0,
    eKernelTypeAccum = (1 << 0),
    eKernelTypeInit = (1 << 1),
    eKernelTypeComb = (1 << 2),
    eKernelTypeOutC = (1 << 3),
    eKernelTypeHalter = (1 << 4)
  };

  RSReduceBreakpointResolver(
      const lldb::BreakpointSP &breakpoint, ConstString reduce_name,
      std::vector<lldb_renderscript::RSModuleDescriptorSP> *rs_modules,
      int kernel_types = eKernelTypeAll)
      : BreakpointResolver(breakpoint, BreakpointResolver::NameResolver),
        m_reduce_name(reduce_name), m_rsmodules(rs_modules),
        m_kernel_types(kernel_types) {
    // The reduce breakpoint resolver handles adding breakpoints for named
    // reductions.
    // Breakpoints will be resolved for all constituent kernels in the named
    // reduction
  }

  void GetDescription(Stream *strm) override {
    if (strm)
      strm->Printf("RenderScript reduce breakpoint for '%s'",
                   m_reduce_name.AsCString());
  }

  void Dump(Stream *s) const override {}

  Searcher::CallbackReturn SearchCallback(SearchFilter &filter,
                                          SymbolContext &context,
                                          Address *addr) override;

  lldb::SearchDepth GetDepth() override { return lldb::eSearchDepthModule; }

  lldb::BreakpointResolverSP
  CopyForBreakpoint(lldb::BreakpointSP &breakpoint) override {
    lldb::BreakpointResolverSP ret_sp(new RSReduceBreakpointResolver(
        breakpoint, m_reduce_name, m_rsmodules, m_kernel_types));
    return ret_sp;
  }

private:
  ConstString m_reduce_name; // The name of the reduction
  std::vector<lldb_renderscript::RSModuleDescriptorSP> *m_rsmodules;
  int m_kernel_types;
};

struct RSKernelDescriptor {
public:
  RSKernelDescriptor(const RSModuleDescriptor *module, llvm::StringRef name,
                     uint32_t slot)
      : m_module(module), m_name(name), m_slot(slot) {}

  void Dump(Stream &strm) const;

  const RSModuleDescriptor *m_module;
  ConstString m_name;
  RSSlot m_slot;
};

struct RSGlobalDescriptor {
public:
  RSGlobalDescriptor(const RSModuleDescriptor *module, llvm::StringRef name)
      : m_module(module), m_name(name) {}

  void Dump(Stream &strm) const;

  const RSModuleDescriptor *m_module;
  ConstString m_name;
};

struct RSReductionDescriptor {
  RSReductionDescriptor(const RSModuleDescriptor *module, uint32_t sig,
                        uint32_t accum_data_size, llvm::StringRef name,
                        llvm::StringRef init_name, llvm::StringRef accum_name,
                        llvm::StringRef comb_name, llvm::StringRef outc_name,
                        llvm::StringRef halter_name = ".")
      : m_module(module), m_reduce_name(name), m_init_name(init_name),
        m_accum_name(accum_name), m_comb_name(comb_name),
        m_outc_name(outc_name), m_halter_name(halter_name) {
    // TODO Check whether the combiner is an autogenerated name, and track
    // this
  }

  void Dump(Stream &strm) const;

  const RSModuleDescriptor *m_module;
  ConstString m_reduce_name; // This is the name given to the general reduction
                             // as a group as passed to pragma
  // reduce(m_reduce_name). There is no kernel function with this name
  ConstString m_init_name;  // The name of the initializer name. "." if no
                            // initializer given
  ConstString m_accum_name; // The accumulator function name. "." if not given
  ConstString m_comb_name; // The name of the combiner function. If this was not
                           // given, a name is generated by the
                           // compiler. TODO
  ConstString m_outc_name; // The name of the outconverter

  ConstString m_halter_name; // The name of the halter function. XXX This is not
                             // yet specified by the RenderScript
  // compiler or runtime, and its semantics and existence is still under
  // discussion by the
  // RenderScript Contributors
  RSSlot m_accum_sig; // metatdata signature for this reduction (bitwise mask of
                      // type information (see
                      // libbcc/include/bcinfo/MetadataExtractor.h
  uint32_t m_accum_data_size; // Data size of the accumulator function input
  bool m_comb_name_generated; // Was the combiner name generated by the compiler
};

class RSModuleDescriptor {
  std::string m_slang_version;
  std::string m_bcc_version;

  bool ParseVersionInfo(llvm::StringRef *, size_t n_lines);

  bool ParseExportForeachCount(llvm::StringRef *, size_t n_lines);

  bool ParseExportVarCount(llvm::StringRef *, size_t n_lines);

  bool ParseExportReduceCount(llvm::StringRef *, size_t n_lines);

  bool ParseBuildChecksum(llvm::StringRef *, size_t n_lines);

  bool ParsePragmaCount(llvm::StringRef *, size_t n_lines);

public:
  RSModuleDescriptor(const lldb::ModuleSP &module) : m_module(module) {}

  ~RSModuleDescriptor() = default;

  bool ParseRSInfo();

  void Dump(Stream &strm) const;

  void WarnIfVersionMismatch(Stream *s) const;

  const lldb::ModuleSP m_module;
  std::vector<RSKernelDescriptor> m_kernels;
  std::vector<RSGlobalDescriptor> m_globals;
  std::vector<RSReductionDescriptor> m_reductions;
  std::map<std::string, std::string> m_pragmas;
  std::string m_resname;
};

struct RSScriptGroupDescriptor {
  struct Kernel {
    ConstString m_name;
    lldb::addr_t m_addr;
  };
  ConstString m_name;
  std::vector<Kernel> m_kernels;
};

typedef std::vector<RSScriptGroupDescriptorSP> RSScriptGroupList;

class RSScriptGroupBreakpointResolver : public BreakpointResolver {
public:
  RSScriptGroupBreakpointResolver(const lldb::BreakpointSP &bp,
                                  ConstString name,
                                  const RSScriptGroupList &groups,
                                  bool stop_on_all)
      : BreakpointResolver(bp, BreakpointResolver::NameResolver),
        m_group_name(name), m_script_groups(groups),
        m_stop_on_all(stop_on_all) {}

  void GetDescription(Stream *strm) override {
    if (strm)
      strm->Printf("RenderScript ScriptGroup breakpoint for '%s'",
                   m_group_name.AsCString());
  }

  void Dump(Stream *s) const override {}

  Searcher::CallbackReturn SearchCallback(SearchFilter &filter,
                                          SymbolContext &context,
                                          Address *addr) override;

  lldb::SearchDepth GetDepth() override { return lldb::eSearchDepthModule; }

  lldb::BreakpointResolverSP
  CopyForBreakpoint(lldb::BreakpointSP &breakpoint) override {
    lldb::BreakpointResolverSP ret_sp(new RSScriptGroupBreakpointResolver(
        breakpoint, m_group_name, m_script_groups, m_stop_on_all));
    return ret_sp;
  }

protected:
  const RSScriptGroupDescriptorSP
  FindScriptGroup(ConstString name) const {
    for (auto sg : m_script_groups) {
      if (ConstString::Compare(sg->m_name, name) == 0)
        return sg;
    }
    return RSScriptGroupDescriptorSP();
  }

  ConstString m_group_name;
  const RSScriptGroupList &m_script_groups;
  bool m_stop_on_all;
};
} // namespace lldb_renderscript

class RenderScriptRuntime : public lldb_private::CPPLanguageRuntime {
public:
  enum ModuleKind {
    eModuleKindIgnored,
    eModuleKindLibRS,
    eModuleKindDriver,
    eModuleKindImpl,
    eModuleKindKernelObj
  };

  ~RenderScriptRuntime() override;

  // Static Functions
  static void Initialize();

  static void Terminate();

  static lldb_private::LanguageRuntime *
  CreateInstance(Process *process, lldb::LanguageType language);

  static lldb::CommandObjectSP
  GetCommandObject(CommandInterpreter &interpreter);

  static llvm::StringRef GetPluginNameStatic() { return "renderscript"; }

  static char ID;

  bool isA(const void *ClassID) const override {
    return ClassID == &ID || CPPLanguageRuntime::isA(ClassID);
  }

  static bool classof(const LanguageRuntime *runtime) {
    return runtime->isA(&ID);
  }

  static bool IsRenderScriptModule(const lldb::ModuleSP &module_sp);

  static ModuleKind GetModuleKind(const lldb::ModuleSP &module_sp);

  static void ModulesDidLoad(const lldb::ProcessSP &process_sp,
                             const ModuleList &module_list);

  bool GetDynamicTypeAndAddress(ValueObject &in_value,
                                lldb::DynamicValueType use_dynamic,
                                TypeAndOrName &class_type_or_name,
                                Address &address,
                                Value::ValueType &value_type) override;

  TypeAndOrName FixUpDynamicType(const TypeAndOrName &type_and_or_name,
                                 ValueObject &static_value) override;

  bool CouldHaveDynamicValue(ValueObject &in_value) override;

  lldb::BreakpointResolverSP
  CreateExceptionResolver(const lldb::BreakpointSP &bp,
                          bool catch_bp, bool throw_bp) override;

  bool LoadModule(const lldb::ModuleSP &module_sp);

  void DumpModules(Stream &strm) const;

  void DumpContexts(Stream &strm) const;

  void DumpKernels(Stream &strm) const;

  bool DumpAllocation(Stream &strm, StackFrame *frame_ptr, const uint32_t id);

  void ListAllocations(Stream &strm, StackFrame *frame_ptr,
                       const uint32_t index);

  bool RecomputeAllAllocations(Stream &strm, StackFrame *frame_ptr);

  bool PlaceBreakpointOnKernel(
      lldb::TargetSP target, Stream &messages, const char *name,
      const lldb_renderscript::RSCoordinate *coords = nullptr);

  bool PlaceBreakpointOnReduction(
      lldb::TargetSP target, Stream &messages, const char *reduce_name,
      const lldb_renderscript::RSCoordinate *coords = nullptr,
      int kernel_types = ~(0));

  bool PlaceBreakpointOnScriptGroup(lldb::TargetSP target, Stream &strm,
                                    ConstString name, bool stop_on_all);

  void SetBreakAllKernels(bool do_break, lldb::TargetSP target);

  void DumpStatus(Stream &strm) const;

  void ModulesDidLoad(const ModuleList &module_list) override;

  bool LoadAllocation(Stream &strm, const uint32_t alloc_id,
                      const char *filename, StackFrame *frame_ptr);

  bool SaveAllocation(Stream &strm, const uint32_t alloc_id,
                      const char *filename, StackFrame *frame_ptr);

  void Update();

  void Initiate();

  const lldb_renderscript::RSScriptGroupList &GetScriptGroups() const {
    return m_scriptGroups;
  };

  bool IsKnownKernel(ConstString name) {
    for (const auto &module : m_rsmodules)
      for (const auto &kernel : module->m_kernels)
        if (kernel.m_name == name)
          return true;
    return false;
  }

  bool GetOverrideExprOptions(clang::TargetOptions &prototype);

  // PluginInterface protocol
  llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); }

  static bool GetKernelCoordinate(lldb_renderscript::RSCoordinate &coord,
                                  Thread *thread_ptr);

  bool ResolveKernelName(lldb::addr_t kernel_address, ConstString &name);

protected:
  struct ScriptDetails;
  struct AllocationDetails;
  struct Element;

  lldb_renderscript::RSScriptGroupList m_scriptGroups;

  void InitSearchFilter(lldb::TargetSP target) {
    if (!m_filtersp)
      m_filtersp =
          std::make_shared<SearchFilterForUnconstrainedSearches>(target);
  }

  void FixupScriptDetails(lldb_renderscript::RSModuleDescriptorSP rsmodule_sp);

  void LoadRuntimeHooks(lldb::ModuleSP module, ModuleKind kind);

  bool RefreshAllocation(AllocationDetails *alloc, StackFrame *frame_ptr);

  bool EvalRSExpression(const char *expression, StackFrame *frame_ptr,
                        uint64_t *result);

  lldb::BreakpointSP CreateScriptGroupBreakpoint(ConstString name,
                                                 bool multi);

  lldb::BreakpointSP CreateKernelBreakpoint(ConstString name);

  lldb::BreakpointSP CreateReductionBreakpoint(ConstString name,
                                               int kernel_types);

  void BreakOnModuleKernels(
      const lldb_renderscript::RSModuleDescriptorSP rsmodule_sp);

  struct RuntimeHook;
  typedef void (RenderScriptRuntime::*CaptureStateFn)(
      RuntimeHook *hook_info,
      ExecutionContext &context); // Please do this!

  struct HookDefn {
    const char *name;
    const char *symbol_name_m32; // mangled name for the 32 bit architectures
    const char *symbol_name_m64; // mangled name for the 64 bit archs
    uint32_t version;
    ModuleKind kind;
    CaptureStateFn grabber;
  };

  struct RuntimeHook {
    lldb::addr_t address;
    const HookDefn *defn;
    lldb::BreakpointSP bp_sp;
  };

  typedef std::shared_ptr<RuntimeHook> RuntimeHookSP;

  lldb::ModuleSP m_libRS;
  lldb::ModuleSP m_libRSDriver;
  lldb::ModuleSP m_libRSCpuRef;
  std::vector<lldb_renderscript::RSModuleDescriptorSP> m_rsmodules;

  std::vector<std::unique_ptr<ScriptDetails>> m_scripts;
  std::vector<std::unique_ptr<AllocationDetails>> m_allocations;

  std::map<lldb::addr_t, lldb_renderscript::RSModuleDescriptorSP>
      m_scriptMappings;
  std::map<lldb::addr_t, RuntimeHookSP> m_runtimeHooks;
  std::map<lldb::user_id_t, std::unique_ptr<lldb_renderscript::RSCoordinate>>
      m_conditional_breaks;

  lldb::SearchFilterSP
      m_filtersp; // Needed to create breakpoints through Target API

  bool m_initiated;
  bool m_debuggerPresentFlagged;
  bool m_breakAllKernels;
  static const HookDefn s_runtimeHookDefns[];
  static const size_t s_runtimeHookCount;
  LLVMUserExpression::IRPasses *m_ir_passes;

private:
  RenderScriptRuntime(Process *process); // Call CreateInstance instead.

  static bool HookCallback(void *baton, StoppointCallbackContext *ctx,
                           lldb::user_id_t break_id,
                           lldb::user_id_t break_loc_id);

  static bool KernelBreakpointHit(void *baton, StoppointCallbackContext *ctx,
                                  lldb::user_id_t break_id,
                                  lldb::user_id_t break_loc_id);

  void HookCallback(RuntimeHook *hook_info, ExecutionContext &context);

  // Callback function when 'debugHintScriptGroup2' executes on the target.
  void CaptureDebugHintScriptGroup2(RuntimeHook *hook_info,
                                    ExecutionContext &context);

  void CaptureScriptInit(RuntimeHook *hook_info, ExecutionContext &context);

  void CaptureAllocationInit(RuntimeHook *hook_info, ExecutionContext &context);

  void CaptureAllocationDestroy(RuntimeHook *hook_info,
                                ExecutionContext &context);

  void CaptureSetGlobalVar(RuntimeHook *hook_info, ExecutionContext &context);

  void CaptureScriptInvokeForEachMulti(RuntimeHook *hook_info,
                                       ExecutionContext &context);

  AllocationDetails *FindAllocByID(Stream &strm, const uint32_t alloc_id);

  std::shared_ptr<uint8_t> GetAllocationData(AllocationDetails *alloc,
                                             StackFrame *frame_ptr);

  void SetElementSize(Element &elem);

  static bool GetFrameVarAsUnsigned(const lldb::StackFrameSP,
                                    const char *var_name, uint64_t &val);

  void FindStructTypeName(Element &elem, StackFrame *frame_ptr);

  size_t PopulateElementHeaders(const std::shared_ptr<uint8_t> header_buffer,
                                size_t offset, const Element &elem);

  size_t CalculateElementHeaderSize(const Element &elem);

  void SetConditional(lldb::BreakpointSP bp, lldb_private::Stream &messages,
                      const lldb_renderscript::RSCoordinate &coord);
  //
  // Helper functions for jitting the runtime
  //

  bool JITDataPointer(AllocationDetails *alloc, StackFrame *frame_ptr,
                      uint32_t x = 0, uint32_t y = 0, uint32_t z = 0);

  bool JITTypePointer(AllocationDetails *alloc, StackFrame *frame_ptr);

  bool JITTypePacked(AllocationDetails *alloc, StackFrame *frame_ptr);

  bool JITElementPacked(Element &elem, const lldb::addr_t context,
                        StackFrame *frame_ptr);

  bool JITAllocationSize(AllocationDetails *alloc, StackFrame *frame_ptr);

  bool JITSubelements(Element &elem, const lldb::addr_t context,
                      StackFrame *frame_ptr);

  bool JITAllocationStride(AllocationDetails *alloc, StackFrame *frame_ptr);

  // Search for a script detail object using a target address.
  // If a script does not currently exist this function will return nullptr.
  // If 'create' is true and there is no previous script with this address,
  // then a new Script detail object will be created for this address and
  // returned.
  ScriptDetails *LookUpScript(lldb::addr_t address, bool create);

  // Search for a previously saved allocation detail object using a target
  // address.
  // If an allocation does not exist for this address then nullptr will be
  // returned.
  AllocationDetails *LookUpAllocation(lldb::addr_t address);

  // Creates a new allocation with the specified address assigning a new ID and
  // removes
  // any previous stored allocation which has the same address.
  AllocationDetails *CreateAllocation(lldb::addr_t address);

  bool GetIRPasses(LLVMUserExpression::IRPasses &passes) override;
};

} // namespace lldb_private

#endif // LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_RENDERSCRIPT_RENDERSCRIPTRUNTIME_RENDERSCRIPTRUNTIME_H
