//===-- ProcessGDBRemote.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_ProcessGDBRemote_h_
#define liblldb_ProcessGDBRemote_h_

// C Includes

// C++ Includes
#include <list>
#include <vector>

// Other libraries and framework includes
#include "lldb/Core/ArchSpec.h"
#include "lldb/Core/Broadcaster.h"
#include "lldb/Core/ConstString.h"
#include "lldb/Core/Error.h"
#include "lldb/Core/StreamString.h"
#include "lldb/Core/StringList.h"
#include "lldb/Core/StructuredData.h"
#include "lldb/Core/ThreadSafeValue.h"
#include "lldb/Host/HostThread.h"
#include "lldb/lldb-private-forward.h"
#include "lldb/Utility/StringExtractor.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/Thread.h"

#include "GDBRemoteCommunicationClient.h"
#include "GDBRemoteRegisterContext.h"

namespace lldb_private {
namespace process_gdb_remote {

class ThreadGDBRemote;

class ProcessGDBRemote : public Process
{
public:
    //------------------------------------------------------------------
    // Constructors and Destructors
    //------------------------------------------------------------------
    static lldb::ProcessSP
    CreateInstance (Target& target, 
                    Listener &listener,
                    const FileSpec *crash_file_path);

    static void
    Initialize();

    static void
    DebuggerInitialize (Debugger &debugger);

    static void
    Terminate();

    static ConstString
    GetPluginNameStatic();

    static const char *
    GetPluginDescriptionStatic();

    //------------------------------------------------------------------
    // Constructors and Destructors
    //------------------------------------------------------------------
    ProcessGDBRemote(Target& target, Listener &listener);

    virtual
    ~ProcessGDBRemote();

    //------------------------------------------------------------------
    // Check if a given Process
    //------------------------------------------------------------------
    bool
    CanDebug (Target &target, bool plugin_specified_by_name) override;

    CommandObject *
    GetPluginCommandObject() override;

    //------------------------------------------------------------------
    // Creating a new process, or attaching to an existing one
    //------------------------------------------------------------------
    Error
    WillLaunch (Module* module) override;

    Error
    DoLaunch (Module *exe_module, ProcessLaunchInfo &launch_info) override;

    void
    DidLaunch () override;

    Error
    WillAttachToProcessWithID (lldb::pid_t pid) override;

    Error
    WillAttachToProcessWithName (const char *process_name, bool wait_for_launch) override;

    Error
    DoConnectRemote (Stream *strm, const char *remote_url) override;
    
    Error
    WillLaunchOrAttach ();
    
    Error
    DoAttachToProcessWithID (lldb::pid_t pid, const ProcessAttachInfo &attach_info) override;
    
    Error
    DoAttachToProcessWithName (const char *process_name,
                               const ProcessAttachInfo &attach_info) override;

    void
    DidAttach (ArchSpec &process_arch) override;

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

    uint32_t
    GetPluginVersion() override;

    //------------------------------------------------------------------
    // Process Control
    //------------------------------------------------------------------
    Error
    WillResume () override;

    Error
    DoResume () override;

    Error
    DoHalt (bool &caused_stop) override;

    Error
    DoDetach (bool keep_stopped) override;
    
    bool
    DetachRequiresHalt() override { return true; }

    Error
    DoSignal (int signal) override;

    Error
    DoDestroy () override;

    void
    RefreshStateAfterStop() override;

    //------------------------------------------------------------------
    // Process Queries
    //------------------------------------------------------------------
    bool
    IsAlive () override;

    lldb::addr_t
    GetImageInfoAddress() override;

    //------------------------------------------------------------------
    // Process Memory
    //------------------------------------------------------------------
    size_t
    DoReadMemory (lldb::addr_t addr, void *buf, size_t size, Error &error) override;

    size_t
    DoWriteMemory (lldb::addr_t addr, const void *buf, size_t size, Error &error) override;

    lldb::addr_t
    DoAllocateMemory (size_t size, uint32_t permissions, Error &error) override;

    Error
    GetMemoryRegionInfo (lldb::addr_t load_addr, MemoryRegionInfo &region_info) override;
    
    Error
    DoDeallocateMemory (lldb::addr_t ptr) override;

    //------------------------------------------------------------------
    // Process STDIO
    //------------------------------------------------------------------
    size_t
    PutSTDIN (const char *buf, size_t buf_size, Error &error) override;

    //----------------------------------------------------------------------
    // Process Breakpoints
    //----------------------------------------------------------------------
    Error
    EnableBreakpointSite (BreakpointSite *bp_site) override;

    Error
    DisableBreakpointSite (BreakpointSite *bp_site) override;

    //----------------------------------------------------------------------
    // Process Watchpoints
    //----------------------------------------------------------------------
    Error
    EnableWatchpoint (Watchpoint *wp, bool notify = true) override;

    Error
    DisableWatchpoint (Watchpoint *wp, bool notify = true) override;

    Error
    GetWatchpointSupportInfo (uint32_t &num) override;
    
    Error
    GetWatchpointSupportInfo (uint32_t &num, bool& after) override;
    
    bool
    StartNoticingNewThreads() override;

    bool
    StopNoticingNewThreads() override;

    GDBRemoteCommunicationClient &
    GetGDBRemote()
    {
        return m_gdb_comm;
    }
    
    Error
    SendEventData(const char *data) override;

    //----------------------------------------------------------------------
    // Override DidExit so we can disconnect from the remote GDB server
    //----------------------------------------------------------------------
    void
    DidExit () override;

    void
    SetUserSpecifiedMaxMemoryTransferSize (uint64_t user_specified_max);

    bool
    GetModuleSpec(const FileSpec& module_file_spec,
                  const ArchSpec& arch,
                  ModuleSpec &module_spec) override;

    size_t
    LoadModules() override;

    Error
    GetFileLoadAddress(const FileSpec& file, bool& is_loaded, lldb::addr_t& load_addr) override;

    void
    ModulesDidLoad (ModuleList &module_list) override;

    StructuredData::ObjectSP
    GetLoadedDynamicLibrariesInfos (lldb::addr_t image_list_address, lldb::addr_t image_count) override;

protected:
    friend class ThreadGDBRemote;
    friend class GDBRemoteCommunicationClient;
    friend class GDBRemoteRegisterContext;

    class GDBLoadedModuleInfoList;

    //----------------------------------------------------------------------
    // Accessors
    //----------------------------------------------------------------------
    bool
    IsRunning ( lldb::StateType state )
    {
        return    state == lldb::eStateRunning || IsStepping(state);
    }

    bool
    IsStepping ( lldb::StateType state)
    {
        return    state == lldb::eStateStepping;
    }
    bool
    CanResume ( lldb::StateType state)
    {
        return state == lldb::eStateStopped;
    }

    bool
    HasExited (lldb::StateType state)
    {
        return state == lldb::eStateExited;
    }

    bool
    ProcessIDIsValid ( ) const;

    void
    Clear ( );

    Flags &
    GetFlags ()
    {
        return m_flags;
    }

    const Flags &
    GetFlags () const
    {
        return m_flags;
    }

    bool
    UpdateThreadList (ThreadList &old_thread_list, 
                      ThreadList &new_thread_list) override;

    Error
    LaunchAndConnectToDebugserver (const ProcessInfo &process_info);

    void
    KillDebugserverProcess ();

    void
    BuildDynamicRegisterInfo (bool force);

    void
    SetLastStopPacket (const StringExtractorGDBRemote &response);

    bool
    ParsePythonTargetDefinition(const FileSpec &target_definition_fspec);

    const lldb::DataBufferSP
    GetAuxvData() override;

    StructuredData::ObjectSP
    GetExtendedInfoForThread (lldb::tid_t tid);

    void
    GetMaxMemorySize();

    bool
    CalculateThreadStopInfo (ThreadGDBRemote *thread);

    size_t
    UpdateThreadIDsFromStopReplyThreadsValue (std::string &value);

    //------------------------------------------------------------------
    /// Broadcaster event bits definitions.
    //------------------------------------------------------------------
    enum
    {
        eBroadcastBitAsyncContinue                  = (1 << 0),
        eBroadcastBitAsyncThreadShouldExit          = (1 << 1),
        eBroadcastBitAsyncThreadDidExit             = (1 << 2)
    };
    
    Flags m_flags;            // Process specific flags (see eFlags enums)
    GDBRemoteCommunicationClient m_gdb_comm;
    std::atomic<lldb::pid_t> m_debugserver_pid;
    std::vector<StringExtractorGDBRemote> m_stop_packet_stack;  // The stop packet stack replaces the last stop packet variable
    Mutex m_last_stop_packet_mutex;
    GDBRemoteDynamicRegisterInfo m_register_info;
    Broadcaster m_async_broadcaster;
    HostThread m_async_thread;
    Mutex m_async_thread_state_mutex;
    typedef std::vector<lldb::tid_t> tid_collection;
    typedef std::vector< std::pair<lldb::tid_t,int> > tid_sig_collection;
    typedef std::map<lldb::addr_t, lldb::addr_t> MMapMap;
    typedef std::map<uint32_t, std::string> ExpeditedRegisterMap;
    tid_collection m_thread_ids; // Thread IDs for all threads. This list gets updated after stopping
    StructuredData::ObjectSP m_threads_info_sp; // Stop info for all threads if "jThreadsInfo" packet is supported
    tid_collection m_continue_c_tids;                  // 'c' for continue
    tid_sig_collection m_continue_C_tids; // 'C' for continue with signal
    tid_collection m_continue_s_tids;                  // 's' for step
    tid_sig_collection m_continue_S_tids; // 'S' for step with signal
    uint64_t m_max_memory_size;       // The maximum number of bytes to read/write when reading and writing memory
    uint64_t m_remote_stub_max_memory_size;    // The maximum memory size the remote gdb stub can handle
    MMapMap m_addr_to_mmap_size;
    lldb::BreakpointSP m_thread_create_bp_sp;
    bool m_waiting_for_attach;
    bool m_destroy_tried_resuming;
    lldb::CommandObjectSP m_command_sp;
    int64_t m_breakpoint_pc_offset;
    lldb::tid_t m_initial_tid; // The inital thread ID, given by stub on attach

    bool
    HandleNotifyPacket(StringExtractorGDBRemote &packet);

    bool
    StartAsyncThread ();

    void
    StopAsyncThread ();

    static lldb::thread_result_t
    AsyncThread (void *arg);

    static bool
    MonitorDebugserverProcess (void *callback_baton,
                               lldb::pid_t pid,
                               bool exited,
                               int signo,
                               int exit_status);

    lldb::StateType
    SetThreadStopInfo (StringExtractor& stop_packet);

    lldb::StateType
    SetThreadStopInfo (StructuredData::Dictionary *thread_dict);

    lldb::ThreadSP
    SetThreadStopInfo (lldb::tid_t tid,
                       ExpeditedRegisterMap &expedited_register_map,
                       uint8_t signo,
                       const std::string &thread_name,
                       const std::string &reason,
                       const std::string &description,
                       uint32_t exc_type,
                       const std::vector<lldb::addr_t> &exc_data,
                       lldb::addr_t thread_dispatch_qaddr,
                       bool queue_vars_valid,
                       std::string &queue_name,
                       lldb::QueueKind queue_kind,
                       uint64_t queue_serial);

    void
    HandleStopReplySequence ();

    void
    ClearThreadIDList ();

    bool
    UpdateThreadIDList ();

    void
    DidLaunchOrAttach (ArchSpec& process_arch);

    Error
    ConnectToDebugserver (const char *host_port);

    const char *
    GetDispatchQueueNameForThread (lldb::addr_t thread_dispatch_qaddr,
                                   std::string &dispatch_queue_name);

    DynamicLoader *
    GetDynamicLoader () override;

    // Query remote GDBServer for register information
    bool
    GetGDBServerRegisterInfo ();

    // Query remote GDBServer for a detailed loaded library list
    Error
    GetLoadedModuleList (GDBLoadedModuleInfoList &);

    lldb::ModuleSP
    LoadModuleAtAddress (const FileSpec &file, lldb::addr_t base_addr);

private:
    //------------------------------------------------------------------
    // For ProcessGDBRemote only
    //------------------------------------------------------------------
    static bool
    NewThreadNotifyBreakpointHit (void *baton,
                         StoppointCallbackContext *context,
                         lldb::user_id_t break_id,
                         lldb::user_id_t break_loc_id);

    DISALLOW_COPY_AND_ASSIGN (ProcessGDBRemote);

};

} // namespace process_gdb_remote
} // namespace lldb_private

#endif  // liblldb_ProcessGDBRemote_h_
