//===-- MachProcess.h -------------------------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
//  Created by Greg Clayton on 6/15/07.
//
//===----------------------------------------------------------------------===//

#ifndef __MachProcess_h__
#define __MachProcess_h__

#include <mach/mach.h>
#include <mach-o/loader.h>
#include <sys/signal.h>
#include <pthread.h>
#include <uuid/uuid.h>
#include <vector>
#include <CoreFoundation/CoreFoundation.h>

#include "DNBDefs.h"
#include "DNBBreakpoint.h"
#include "DNBError.h"
#include "DNBThreadResumeActions.h"
#include "MachException.h"
#include "MachVMMemory.h"
#include "MachTask.h"
#include "MachThreadList.h"
#include "PThreadCondition.h"
#include "PThreadEvent.h"
#include "PThreadMutex.h"
#include "Genealogy.h"
#include "ThreadInfo.h"
#include "JSONGenerator.h"

class DNBThreadResumeActions;

class MachProcess
{
public:
    //----------------------------------------------------------------------
    // Constructors and Destructors
    //----------------------------------------------------------------------
    MachProcess ();
    ~MachProcess ();

    // A structure that can hold everything debugserver needs to know from
    // a binary's Mach-O header / load commands.

    struct mach_o_segment
    {
        std::string name;
        uint64_t vmaddr;
        uint64_t vmsize;
        uint64_t fileoff;
        uint64_t filesize;
        uint64_t maxprot;
        uint64_t initprot;
        uint64_t nsects;
        uint64_t flags;
    };

    struct mach_o_information
    {
        struct mach_header_64 mach_header;
        std::vector<struct mach_o_segment> segments;
        uuid_t uuid;
        std::string min_version_os_name;
        std::string min_version_os_version;
    };

    struct binary_image_information
    {
        std::string filename;
        uint64_t    load_address;
        uint64_t    mod_date;      // may not be available - 0 if so
        struct mach_o_information macho_info;

        binary_image_information () : 
            filename (),
            load_address (INVALID_NUB_ADDRESS),
            mod_date (0)
            { }
    };

    //----------------------------------------------------------------------
    // Child process control
    //----------------------------------------------------------------------
    pid_t                   AttachForDebug (pid_t pid, char *err_str, size_t err_len);
    pid_t                   LaunchForDebug (const char *path, 
                                            char const *argv[], 
                                            char const *envp[], 
                                            const char *working_directory,
                                            const char *stdin_path,
                                            const char *stdout_path,
                                            const char *stderr_path,
                                            bool no_stdio, 
                                            nub_launch_flavor_t launch_flavor, 
                                            int disable_aslr,
                                            const char *event_data,
                                            DNBError &err);

    static uint32_t         GetCPUTypeForLocalProcess (pid_t pid);
    static pid_t            ForkChildForPTraceDebugging (const char *path, char const *argv[], char const *envp[], MachProcess* process, DNBError &err);
    static pid_t            PosixSpawnChildForPTraceDebugging (const char *path, 
                                                               cpu_type_t cpu_type, 
                                                               char const *argv[], 
                                                               char const *envp[], 
                                                               const char *working_directory,
                                                               const char *stdin_path,
                                                               const char *stdout_path,
                                                               const char *stderr_path,
                                                               bool no_stdio, 
                                                               MachProcess* process, 
                                                               int disable_aslr, 
                                                               DNBError& err);
    nub_addr_t              GetDYLDAllImageInfosAddress ();
    static const void *     PrepareForAttach (const char *path, nub_launch_flavor_t launch_flavor, bool waitfor, DNBError &err_str);
    static void             CleanupAfterAttach (const void *attach_token, nub_launch_flavor_t launch_flavor, bool success, DNBError &err_str);
    static nub_process_t    CheckForProcess (const void *attach_token, nub_launch_flavor_t launch_flavor);
#if defined(WITH_BKS) || defined(WITH_FBS)
    pid_t                   BoardServiceLaunchForDebug (const char *app_bundle_path, char const *argv[], char const *envp[], bool no_stdio, bool disable_aslr, const char *event_data, DNBError &launch_err);
    pid_t                   BoardServiceForkChildForPTraceDebugging (const char *path, char const *argv[], char const *envp[], bool no_stdio, bool disable_aslr, const char *event_data, DNBError &launch_err);
    bool                    BoardServiceSendEvent (const char *event, DNBError &error);
#endif
    static bool             GetOSVersionNumbers (uint64_t *major, uint64_t *minor, uint64_t *patch);
#ifdef WITH_BKS
    static void             BKSCleanupAfterAttach (const void *attach_token, DNBError &err_str);
#endif // WITH_BKS
#ifdef WITH_FBS
    static void             FBSCleanupAfterAttach (const void *attach_token, DNBError &err_str);
#endif  // WITH_FBS
#ifdef WITH_SPRINGBOARD
    pid_t                   SBLaunchForDebug (const char *app_bundle_path, char const *argv[], char const *envp[], bool no_stdio, bool disable_aslr, DNBError &launch_err);
    static pid_t            SBForkChildForPTraceDebugging (const char *path, char const *argv[], char const *envp[], bool no_stdio, MachProcess* process, DNBError &launch_err);
#endif  // WITH_SPRINGBOARD
    nub_addr_t              LookupSymbol (const char *name, const char *shlib);
    void                    SetNameToAddressCallback (DNBCallbackNameToAddress callback, void *baton)
                            {
                                m_name_to_addr_callback = callback;
                                m_name_to_addr_baton    = baton;
                            }
    void                    SetSharedLibraryInfoCallback (DNBCallbackCopyExecutableImageInfos callback, void *baton)
                            {
                                m_image_infos_callback    = callback;
                                m_image_infos_baton        = baton;
                            }

    bool                    Resume (const DNBThreadResumeActions& thread_actions);
    bool                    Signal  (int signal, const struct timespec *timeout_abstime = NULL);
    bool                    Interrupt();
    bool                    SendEvent (const char *event, DNBError &send_err);
    bool                    Kill (const struct timespec *timeout_abstime = NULL);
    bool                    Detach ();
    nub_size_t              ReadMemory (nub_addr_t addr, nub_size_t size, void *buf);
    nub_size_t              WriteMemory (nub_addr_t addr, nub_size_t size, const void *buf);

    //----------------------------------------------------------------------
    // Path and arg accessors
    //----------------------------------------------------------------------
    const char *            Path () const { return m_path.c_str(); }
    size_t                  ArgumentCount () const { return m_args.size(); }
    const char *            ArgumentAtIndex (size_t arg_idx) const
                            {
                                if (arg_idx < m_args.size())
                                    return m_args[arg_idx].c_str();
                                return NULL;
                            }

    //----------------------------------------------------------------------
    // Breakpoint functions
    //----------------------------------------------------------------------
    DNBBreakpoint *         CreateBreakpoint (nub_addr_t addr, nub_size_t length, bool hardware);
    bool                    DisableBreakpoint (nub_addr_t addr, bool remove);
    void                    DisableAllBreakpoints (bool remove);
    bool                    EnableBreakpoint (nub_addr_t addr);
    DNBBreakpointList&      Breakpoints() { return m_breakpoints; }
    const DNBBreakpointList& Breakpoints() const { return m_breakpoints; }

    //----------------------------------------------------------------------
    // Watchpoint functions
    //----------------------------------------------------------------------
    DNBBreakpoint *         CreateWatchpoint (nub_addr_t addr, nub_size_t length, uint32_t watch_type, bool hardware);
    bool                    DisableWatchpoint (nub_addr_t addr, bool remove);
    void                    DisableAllWatchpoints (bool remove);
    bool                    EnableWatchpoint (nub_addr_t addr);
    uint32_t                GetNumSupportedHardwareWatchpoints () const;
    DNBBreakpointList&      Watchpoints() { return m_watchpoints; }
    const DNBBreakpointList& Watchpoints() const { return m_watchpoints; }

    //----------------------------------------------------------------------
    // Exception thread functions
    //----------------------------------------------------------------------
    bool                    StartSTDIOThread ();
    static void *           STDIOThread (void *arg);
    void                    ExceptionMessageReceived (const MachException::Message& exceptionMessage);
    task_t                  ExceptionMessageBundleComplete ();
    void                    SharedLibrariesUpdated ();
    nub_size_t              CopyImageInfos (struct DNBExecutableImageInfo **image_infos, bool only_changed);
    
    //----------------------------------------------------------------------
    // Profile functions
    //----------------------------------------------------------------------
    void                    SetEnableAsyncProfiling (bool enable, uint64_t internal_usec, DNBProfileDataScanType scan_type);
    bool                    IsProfilingEnabled () { return m_profile_enabled; }
    useconds_t                ProfileInterval () { return m_profile_interval_usec; }
    bool                    StartProfileThread ();
    static void *           ProfileThread (void *arg);
    void                    SignalAsyncProfileData (const char *info);
    size_t                  GetAsyncProfileData (char *buf, size_t buf_size);

    //----------------------------------------------------------------------
    // Accessors
    //----------------------------------------------------------------------
    pid_t                   ProcessID () const { return m_pid; }
    bool                    ProcessIDIsValid () const { return m_pid > 0; }
    pid_t                   SetProcessID (pid_t pid);
    MachTask&               Task() { return m_task; }
    const MachTask&         Task() const { return m_task; }

    PThreadEvent&           Events() { return m_events; }
    const DNBRegisterSetInfo *
                            GetRegisterSetInfo (nub_thread_t tid, nub_size_t *num_reg_sets) const;
    bool                    GetRegisterValue (nub_thread_t tid, uint32_t set, uint32_t reg, DNBRegisterValue *reg_value) const;
    bool                    SetRegisterValue (nub_thread_t tid, uint32_t set, uint32_t reg, const DNBRegisterValue *value) const;
    nub_bool_t              SyncThreadState (nub_thread_t tid);
    const char *            ThreadGetName (nub_thread_t tid);
    nub_state_t             ThreadGetState (nub_thread_t tid);
    ThreadInfo::QoS         GetRequestedQoS (nub_thread_t tid, nub_addr_t tsd, uint64_t dti_qos_class_index);
    nub_addr_t              GetPThreadT (nub_thread_t tid);
    nub_addr_t              GetDispatchQueueT (nub_thread_t tid);
    nub_addr_t              GetTSDAddressForThread (nub_thread_t tid, uint64_t plo_pthread_tsd_base_address_offset, uint64_t plo_pthread_tsd_base_offset, uint64_t plo_pthread_tsd_entry_size);


    bool                    GetMachOInformationFromMemory (nub_addr_t mach_o_header_addr, int wordsize, struct mach_o_information &inf);
    JSONGenerator::ObjectSP FormatDynamicLibrariesIntoJSON (const std::vector<struct binary_image_information> &image_infos);
    void                    GetAllLoadedBinariesViaDYLDSPI (std::vector<struct binary_image_information> &image_infos);
    JSONGenerator::ObjectSP GetLoadedDynamicLibrariesInfos (nub_process_t pid, nub_addr_t image_list_address, nub_addr_t image_count);
    JSONGenerator::ObjectSP GetLibrariesInfoForAddresses (nub_process_t pid, std::vector<uint64_t> &macho_addresses);
    JSONGenerator::ObjectSP GetAllLoadedLibrariesInfos (nub_process_t pid);
    JSONGenerator::ObjectSP GetSharedCacheInfo (nub_process_t pid);

    nub_size_t              GetNumThreads () const;
    nub_thread_t            GetThreadAtIndex (nub_size_t thread_idx) const;
    nub_thread_t            GetCurrentThread ();
    nub_thread_t            GetCurrentThreadMachPort ();
    nub_thread_t            SetCurrentThread (nub_thread_t tid);
    MachThreadList &        GetThreadList() { return m_thread_list; }
    bool                    GetThreadStoppedReason(nub_thread_t tid, struct DNBThreadStopInfo *stop_info);
    void                    DumpThreadStoppedReason(nub_thread_t tid) const;
    const char *            GetThreadInfo (nub_thread_t tid) const;

    nub_thread_t            GetThreadIDForMachPortNumber (thread_t mach_port_number) const;

    uint32_t                GetCPUType ();
    nub_state_t             GetState ();
    void                    SetState (nub_state_t state);
    bool                    IsRunning (nub_state_t state)
                            {
                                return    state == eStateRunning || IsStepping(state);
                            }
    bool                    IsStepping (nub_state_t state)
                            {
                                return    state == eStateStepping;
                            }
    bool                    CanResume (nub_state_t state)
                            {
                                return state == eStateStopped;
                            }

    bool                    GetExitStatus(int* status)
                            {
                                if (GetState() == eStateExited)
                                {
                                    if (status)
                                        *status = m_exit_status;
                                    return true;
                                }
                                return false;
                            }
    void                    SetExitStatus(int status)
                            {
                                m_exit_status = status;
                                SetState(eStateExited);
                            }
    const char *            GetExitInfo ()
                            {
                                return m_exit_info.c_str();
                            }
    
    void                    SetExitInfo (const char *info);

    uint32_t                StopCount() const { return m_stop_count; }
    void                    SetChildFileDescriptors (int stdin_fileno, int stdout_fileno, int stderr_fileno)
                            {
                                m_child_stdin   = stdin_fileno;
                                m_child_stdout  = stdout_fileno;
                                m_child_stderr  = stderr_fileno;
                            }

    int                     GetStdinFileDescriptor () const { return m_child_stdin; }
    int                     GetStdoutFileDescriptor () const { return m_child_stdout; }
    int                     GetStderrFileDescriptor () const { return m_child_stderr; }
    void                    AppendSTDOUT (char* s, size_t len);
    size_t                  GetAvailableSTDOUT (char *buf, size_t buf_size);
    size_t                  GetAvailableSTDERR (char *buf, size_t buf_size);
    void                    CloseChildFileDescriptors ()
                            {
                                if (m_child_stdin >= 0)
                                {
                                    ::close (m_child_stdin);
                                    m_child_stdin = -1;
                                }
                                if (m_child_stdout >= 0)
                                {
                                    ::close (m_child_stdout);
                                    m_child_stdout = -1;
                                }
                                if (m_child_stderr >= 0)
                                {
                                    ::close (m_child_stderr);
                                    m_child_stderr = -1;
                                }
                            }

    bool                    ProcessUsingSpringBoard() const { return (m_flags & eMachProcessFlagsUsingSBS) != 0; }
    bool                    ProcessUsingBackBoard() const { return (m_flags & eMachProcessFlagsUsingBKS) != 0; }

    Genealogy::ThreadActivitySP GetGenealogyInfoForThread (nub_thread_t tid, bool &timed_out);

    Genealogy::ProcessExecutableInfoSP GetGenealogyImageInfo (size_t idx);

    DNBProfileDataScanType  GetProfileScanType () { return m_profile_scan_type; }

private:
    enum
    {
        eMachProcessFlagsNone = 0,
        eMachProcessFlagsAttached = (1 << 0),
        eMachProcessFlagsUsingSBS = (1 << 1),
        eMachProcessFlagsUsingBKS = (1 << 2),
        eMachProcessFlagsUsingFBS = (1 << 3)
    };
    void                    Clear (bool detaching = false);
    void                    ReplyToAllExceptions ();
    void                    PrivateResume ();

    uint32_t                Flags () const { return m_flags; }
    nub_state_t             DoSIGSTOP (bool clear_bps_and_wps, bool allow_running, uint32_t *thread_idx_ptr);

    pid_t                       m_pid;                      // Process ID of child process
    cpu_type_t                  m_cpu_type;                 // The CPU type of this process
    int                         m_child_stdin;
    int                         m_child_stdout;
    int                         m_child_stderr;
    std::string                 m_path;                     // A path to the executable if we have one
    std::vector<std::string>    m_args;                     // The arguments with which the process was lauched
    int                         m_exit_status;              // The exit status for the process
    std::string                 m_exit_info;                // Any extra info that we may have about the exit
    MachTask                    m_task;                     // The mach task for this process
    uint32_t                    m_flags;                    // Process specific flags (see eMachProcessFlags enums)
    uint32_t                    m_stop_count;               // A count of many times have we stopped
    pthread_t                   m_stdio_thread;             // Thread ID for the thread that watches for child process stdio
    PThreadMutex                m_stdio_mutex;              // Multithreaded protection for stdio
    std::string                 m_stdout_data;
    
    bool                        m_profile_enabled;          // A flag to indicate if profiling is enabled
    useconds_t                  m_profile_interval_usec;    // If enable, the profiling interval in microseconds
    DNBProfileDataScanType      m_profile_scan_type;        // Indicates what needs to be profiled
    pthread_t                   m_profile_thread;           // Thread ID for the thread that profiles the inferior
    PThreadMutex                m_profile_data_mutex;       // Multithreaded protection for profile info data
    std::vector<std::string>    m_profile_data;             // Profile data, must be protected by m_profile_data_mutex
    
    DNBThreadResumeActions      m_thread_actions;           // The thread actions for the current MachProcess::Resume() call
    MachException::Message::collection
                                m_exception_messages;       // A collection of exception messages caught when listening to the exception port
    PThreadMutex                m_exception_messages_mutex; // Multithreaded protection for m_exception_messages

    MachThreadList              m_thread_list;               // A list of threads that is maintained/updated after each stop
    Genealogy                   m_activities;               // A list of activities that is updated after every stop lazily
    nub_state_t                 m_state;                    // The state of our process
    PThreadMutex                m_state_mutex;              // Multithreaded protection for m_state
    PThreadEvent                m_events;                   // Process related events in the child processes lifetime can be waited upon
    PThreadEvent                m_private_events;           // Used to coordinate running and stopping the process without affecting m_events
    DNBBreakpointList           m_breakpoints;              // Breakpoint list for this process
    DNBBreakpointList           m_watchpoints;              // Watchpoint list for this process
    DNBCallbackNameToAddress    m_name_to_addr_callback;
    void *                      m_name_to_addr_baton;
    DNBCallbackCopyExecutableImageInfos
                                m_image_infos_callback;
    void *                      m_image_infos_baton;
    std::string                 m_bundle_id;                 // If we are a SB or BKS process, this will be our bundle ID.
    int                         m_sent_interrupt_signo;      // When we call MachProcess::Interrupt(), we want to send a single signal
                                                             // to the inferior and only send the signal if we aren't already stopped.
                                                             // If we end up sending a signal to stop the process we store it until we
                                                             // receive an exception with this signal. This helps us to verify we got
                                                             // the signal that interrupted the process. We might stop due to another
                                                             // reason after an interrupt signal is sent, so this helps us ensure that
                                                             // we don't report a spurious stop on the next resume.
    int                         m_auto_resume_signo;         // If we resume the process and still haven't received our interrupt signal
                                                             // acknownledgement, we will shortly after the next resume. We store the
                                                             // interrupt signal in this variable so when we get the interrupt signal
                                                             // as the sole reason for the process being stopped, we can auto resume
                                                             // the process.
    bool                        m_did_exec;

    void * (*m_dyld_process_info_create) (task_t task, uint64_t timestamp, kern_return_t* kernelError);
    void   (*m_dyld_process_info_for_each_image) (void* info, void (^callback)(uint64_t machHeaderAddress, const uuid_t uuid, const char* path));
    void   (*m_dyld_process_info_release) (void* info);
    void   (*m_dyld_process_info_get_cache) (void* info, void* cacheInfo);
};


#endif // __MachProcess_h__
