1258882Semaste//===-- Debug.h -------------------------------------------------*- C++ -*-===//
2258882Semaste//
3258882Semaste//                     The LLVM Compiler Infrastructure
4258882Semaste//
5258882Semaste// This file is distributed under the University of Illinois Open Source
6258882Semaste// License. See LICENSE.TXT for details.
7258882Semaste//
8258882Semaste//===----------------------------------------------------------------------===//
9258882Semaste
10258882Semaste#ifndef liblldb_Debug_h_
11258882Semaste#define liblldb_Debug_h_
12258882Semaste
13258882Semaste#include "lldb/lldb-private.h"
14258882Semaste#include "lldb/Core/Error.h"
15258882Semaste#include "lldb/Core/StreamString.h"
16258882Semaste#include "lldb/Host/Mutex.h"
17258882Semaste#include <vector>
18258882Semaste
19258882Semastenamespace lldb_private {
20258882Semaste
21258882Semaste    //------------------------------------------------------------------
22258882Semaste    // Tells a thread what it needs to do when the process is resumed.
23258882Semaste    //------------------------------------------------------------------
24258882Semaste    struct ResumeAction
25258882Semaste    {
26258882Semaste        lldb::tid_t tid;        // The thread ID that this action applies to, LLDB_INVALID_THREAD_ID for the default thread action
27258882Semaste        lldb::StateType state;  // Valid values are eStateStopped/eStateSuspended, eStateRunning, and eStateStepping.
28258882Semaste        int signal;             // When resuming this thread, resume it with this signal if this value is > 0
29258882Semaste    };
30258882Semaste
31258882Semaste    //------------------------------------------------------------------
32258882Semaste    // A class that contains instructions for all threads for
33258882Semaste    // NativeProcessProtocol::Resume(). Each thread can either run, stay
34258882Semaste    // suspended, or step when the process is resumed. We optionally
35258882Semaste    // have the ability to also send a signal to the thread when the
36258882Semaste    // action is run or step.
37258882Semaste    //------------------------------------------------------------------
38258882Semaste    class ResumeActionList
39258882Semaste    {
40258882Semaste    public:
41258882Semaste        ResumeActionList () :
42258882Semaste            m_actions (),
43258882Semaste            m_signal_handled ()
44258882Semaste        {
45258882Semaste        }
46258882Semaste
47258882Semaste        ResumeActionList (lldb::StateType default_action, int signal) :
48258882Semaste            m_actions(),
49258882Semaste            m_signal_handled ()
50258882Semaste        {
51258882Semaste            SetDefaultThreadActionIfNeeded (default_action, signal);
52258882Semaste        }
53258882Semaste
54258882Semaste
55258882Semaste        ResumeActionList (const ResumeAction *actions, size_t num_actions) :
56258882Semaste            m_actions (),
57258882Semaste            m_signal_handled ()
58258882Semaste        {
59258882Semaste            if (actions && num_actions)
60258882Semaste            {
61258882Semaste                m_actions.assign (actions, actions + num_actions);
62258882Semaste                m_signal_handled.assign (num_actions, false);
63258882Semaste            }
64258882Semaste        }
65258882Semaste
66258882Semaste        ~ResumeActionList()
67258882Semaste        {
68258882Semaste        }
69258882Semaste
70258882Semaste        bool
71258882Semaste        IsEmpty() const
72258882Semaste        {
73258882Semaste            return m_actions.empty();
74258882Semaste        }
75258882Semaste
76258882Semaste        void
77258882Semaste        Append (const ResumeAction &action)
78258882Semaste        {
79258882Semaste            m_actions.push_back (action);
80258882Semaste            m_signal_handled.push_back (false);
81258882Semaste        }
82258882Semaste
83258882Semaste        void
84258882Semaste        AppendAction (lldb::tid_t tid,
85258882Semaste                      lldb::StateType state,
86258882Semaste                      int signal = 0)
87258882Semaste        {
88258882Semaste            ResumeAction action = { tid, state, signal };
89258882Semaste            Append (action);
90258882Semaste        }
91258882Semaste
92258882Semaste        void
93258882Semaste        AppendResumeAll ()
94258882Semaste        {
95258882Semaste            AppendAction (LLDB_INVALID_THREAD_ID, lldb::eStateRunning);
96258882Semaste        }
97258882Semaste
98258882Semaste        void
99258882Semaste        AppendSuspendAll ()
100258882Semaste        {
101258882Semaste            AppendAction (LLDB_INVALID_THREAD_ID, lldb::eStateStopped);
102258882Semaste        }
103258882Semaste
104258882Semaste        void
105258882Semaste        AppendStepAll ()
106258882Semaste        {
107258882Semaste            AppendAction (LLDB_INVALID_THREAD_ID, lldb::eStateStepping);
108258882Semaste        }
109258882Semaste
110258882Semaste        const ResumeAction *
111258882Semaste        GetActionForThread (lldb::tid_t tid, bool default_ok) const
112258882Semaste        {
113258882Semaste            const size_t num_actions = m_actions.size();
114258882Semaste            for (size_t i=0; i<num_actions; ++i)
115258882Semaste            {
116258882Semaste                if (m_actions[i].tid == tid)
117258882Semaste                    return &m_actions[i];
118258882Semaste            }
119258882Semaste            if (default_ok && tid != LLDB_INVALID_THREAD_ID)
120258882Semaste                return GetActionForThread (LLDB_INVALID_THREAD_ID, false);
121258882Semaste            return NULL;
122258882Semaste        }
123258882Semaste
124258882Semaste        size_t
125258882Semaste        NumActionsWithState (lldb::StateType state) const
126258882Semaste        {
127258882Semaste            size_t count = 0;
128258882Semaste            const size_t num_actions = m_actions.size();
129258882Semaste            for (size_t i=0; i<num_actions; ++i)
130258882Semaste            {
131258882Semaste                if (m_actions[i].state == state)
132258882Semaste                    ++count;
133258882Semaste            }
134258882Semaste            return count;
135258882Semaste        }
136258882Semaste
137258882Semaste        bool
138258882Semaste        SetDefaultThreadActionIfNeeded (lldb::StateType action, int signal)
139258882Semaste        {
140258882Semaste            if (GetActionForThread (LLDB_INVALID_THREAD_ID, true) == NULL)
141258882Semaste            {
142258882Semaste                // There isn't a default action so we do need to set it.
143258882Semaste                ResumeAction default_action = {LLDB_INVALID_THREAD_ID, action, signal };
144258882Semaste                m_actions.push_back (default_action);
145258882Semaste                m_signal_handled.push_back (false);
146258882Semaste                return true; // Return true as we did add the default action
147258882Semaste            }
148258882Semaste            return false;
149258882Semaste        }
150258882Semaste
151258882Semaste        void
152258882Semaste        SetSignalHandledForThread (lldb::tid_t tid) const
153258882Semaste        {
154258882Semaste            if (tid != LLDB_INVALID_THREAD_ID)
155258882Semaste            {
156258882Semaste                const size_t num_actions = m_actions.size();
157258882Semaste                for (size_t i=0; i<num_actions; ++i)
158258882Semaste                {
159258882Semaste                    if (m_actions[i].tid == tid)
160258882Semaste                        m_signal_handled[i] = true;
161258882Semaste                }
162258882Semaste            }
163258882Semaste        }
164258882Semaste
165258882Semaste        const ResumeAction *
166258882Semaste        GetFirst() const
167258882Semaste        {
168258882Semaste            return m_actions.data();
169258882Semaste        }
170258882Semaste
171258882Semaste        size_t
172258882Semaste        GetSize () const
173258882Semaste        {
174258882Semaste            return m_actions.size();
175258882Semaste        }
176258882Semaste
177258882Semaste        void
178258882Semaste        Clear()
179258882Semaste        {
180258882Semaste            m_actions.clear();
181258882Semaste            m_signal_handled.clear();
182258882Semaste        }
183258882Semaste
184258882Semaste    protected:
185258882Semaste        std::vector<ResumeAction> m_actions;
186258882Semaste        mutable std::vector<bool> m_signal_handled;
187258882Semaste    };
188258882Semaste
189258882Semaste    struct ThreadStopInfo
190258882Semaste    {
191258882Semaste        lldb::StopReason reason;
192258882Semaste        union
193258882Semaste        {
194258882Semaste            // eStopTypeSignal
195258882Semaste            struct
196258882Semaste            {
197258882Semaste                uint32_t signo;
198258882Semaste            } signal;
199258882Semaste
200258882Semaste            // eStopTypeException
201258882Semaste            struct
202258882Semaste            {
203258882Semaste                uint64_t type;
204258882Semaste                uint32_t data_count;
205258882Semaste                lldb::addr_t data[2];
206258882Semaste            } exception;
207258882Semaste        } details;
208258882Semaste    };
209258882Semaste
210258882Semaste    //------------------------------------------------------------------
211258882Semaste    // NativeThreadProtocol
212258882Semaste    //------------------------------------------------------------------
213258882Semaste    class NativeThreadProtocol {
214258882Semaste
215258882Semaste    public:
216258882Semaste        NativeThreadProtocol (NativeProcessProtocol *process, lldb::tid_t tid) :
217258882Semaste            m_process (process),
218258882Semaste            m_tid (tid)
219258882Semaste        {
220258882Semaste        }
221258882Semaste
222258882Semaste        virtual ~NativeThreadProtocol()
223258882Semaste        {
224258882Semaste        }
225258882Semaste        virtual const char *GetName() = 0;
226258882Semaste        virtual lldb::StateType GetState () = 0;
227258882Semaste        virtual Error ReadRegister (uint32_t reg, RegisterValue &reg_value) = 0;
228258882Semaste        virtual Error WriteRegister (uint32_t reg, const RegisterValue &reg_value) = 0;
229258882Semaste        virtual Error SaveAllRegisters (lldb::DataBufferSP &data_sp) = 0;
230258882Semaste        virtual Error RestoreAllRegisters (lldb::DataBufferSP &data_sp) = 0;
231258882Semaste        virtual bool GetStopReason (ThreadStopInfo &stop_info) = 0;
232258882Semaste
233258882Semaste        lldb::tid_t
234258882Semaste        GetID() const
235258882Semaste        {
236258882Semaste            return m_tid;
237258882Semaste        }
238258882Semaste    protected:
239258882Semaste        NativeProcessProtocol *m_process;
240258882Semaste        lldb::tid_t m_tid;
241258882Semaste    };
242258882Semaste
243258882Semaste
244258882Semaste    //------------------------------------------------------------------
245258882Semaste    // NativeProcessProtocol
246258882Semaste    //------------------------------------------------------------------
247258882Semaste    class NativeProcessProtocol {
248258882Semaste    public:
249258882Semaste
250258882Semaste        static NativeProcessProtocol *
251258882Semaste        CreateInstance (lldb::pid_t pid);
252258882Semaste
253258882Semaste        // lldb_private::Host calls should be used to launch a process for debugging, and
254258882Semaste        // then the process should be attached to. When attaching to a process
255258882Semaste        // lldb_private::Host calls should be used to locate the process to attach to,
256258882Semaste        // and then this function should be called.
257258882Semaste        NativeProcessProtocol (lldb::pid_t pid) :
258258882Semaste            m_pid (pid),
259258882Semaste            m_threads(),
260258882Semaste            m_threads_mutex (Mutex::eMutexTypeRecursive),
261258882Semaste            m_state (lldb::eStateInvalid),
262258882Semaste            m_exit_status(0),
263258882Semaste            m_exit_description()
264258882Semaste        {
265258882Semaste        }
266258882Semaste
267258882Semaste    public:
268258882Semaste        virtual ~NativeProcessProtocol ()
269258882Semaste        {
270258882Semaste        }
271258882Semaste
272258882Semaste        virtual Error Resume (const ResumeActionList &resume_actions) = 0;
273258882Semaste        virtual Error Halt () = 0;
274258882Semaste        virtual Error Detach () = 0;
275258882Semaste        virtual Error Signal (int signo) = 0;
276258882Semaste        virtual Error Kill () = 0;
277258882Semaste
278258882Semaste        virtual Error ReadMemory (lldb::addr_t addr, void *buf, lldb::addr_t size, lldb::addr_t &bytes_read) = 0;
279258882Semaste        virtual Error WriteMemory (lldb::addr_t addr, const void *buf, lldb::addr_t size, lldb::addr_t &bytes_written) = 0;
280258882Semaste        virtual Error AllocateMemory (lldb::addr_t size, uint32_t permissions, lldb::addr_t &addr) = 0;
281258882Semaste        virtual Error DeallocateMemory (lldb::addr_t addr) = 0;
282258882Semaste
283258882Semaste        virtual lldb::addr_t GetSharedLibraryInfoAddress () = 0;
284258882Semaste
285258882Semaste        virtual bool IsAlive () = 0;
286258882Semaste        virtual size_t UpdateThreads () = 0;
287258882Semaste        virtual bool GetArchitecture (ArchSpec &arch) = 0;
288258882Semaste
289258882Semaste        //----------------------------------------------------------------------
290258882Semaste        // Breakpoint functions
291258882Semaste        //----------------------------------------------------------------------
292258882Semaste        virtual Error SetBreakpoint (lldb::addr_t addr, size_t size, bool hardware) = 0;
293258882Semaste        virtual Error RemoveBreakpoint (lldb::addr_t addr, size_t size) = 0;
294258882Semaste
295258882Semaste        //----------------------------------------------------------------------
296258882Semaste        // Watchpoint functions
297258882Semaste        //----------------------------------------------------------------------
298258882Semaste        virtual uint32_t GetMaxWatchpoints () = 0;
299258882Semaste        virtual Error SetWatchpoint (lldb::addr_t addr, size_t size, uint32_t watch_flags, bool hardware) = 0;
300258882Semaste        virtual Error RemoveWatchpoint (lldb::addr_t addr) = 0;
301258882Semaste
302258882Semaste
303258882Semaste        //----------------------------------------------------------------------
304258882Semaste        // Accessors
305258882Semaste        //----------------------------------------------------------------------
306258882Semaste        lldb::pid_t
307258882Semaste        GetID() const
308258882Semaste        {
309258882Semaste            return m_pid;
310258882Semaste        }
311258882Semaste
312258882Semaste        lldb::StateType
313258882Semaste        GetState () const
314258882Semaste        {
315258882Semaste            return m_state;
316258882Semaste        }
317258882Semaste
318258882Semaste        bool
319258882Semaste        IsRunning () const
320258882Semaste        {
321258882Semaste            return m_state == lldb::eStateRunning || IsStepping();
322258882Semaste        }
323258882Semaste
324258882Semaste        bool
325258882Semaste        IsStepping () const
326258882Semaste        {
327258882Semaste            return m_state == lldb::eStateStepping;
328258882Semaste        }
329258882Semaste
330258882Semaste        bool
331258882Semaste        CanResume () const
332258882Semaste        {
333258882Semaste            return m_state == lldb::eStateStopped;
334258882Semaste        }
335258882Semaste
336258882Semaste
337258882Semaste        void
338258882Semaste        SetState (lldb::StateType state)
339258882Semaste        {
340258882Semaste            m_state = state;
341258882Semaste        }
342258882Semaste
343258882Semaste        //----------------------------------------------------------------------
344258882Semaste        // Exit Status
345258882Semaste        //----------------------------------------------------------------------
346258882Semaste        virtual bool
347258882Semaste        GetExitStatus (int *status)
348258882Semaste        {
349258882Semaste            if (m_state == lldb::eStateExited)
350258882Semaste            {
351258882Semaste                *status = m_exit_status;
352258882Semaste                return true;
353258882Semaste            }
354258882Semaste            *status = 0;
355258882Semaste            return false;
356258882Semaste        }
357258882Semaste        virtual bool
358258882Semaste        SetExitStatus (int status, const char *exit_description)
359258882Semaste        {
360258882Semaste            // Exit status already set
361258882Semaste            if (m_state == lldb::eStateExited)
362258882Semaste                return false;
363258882Semaste            m_state = lldb::eStateExited;
364258882Semaste            m_exit_status = status;
365258882Semaste            if (exit_description && exit_description[0])
366258882Semaste                m_exit_description = exit_description;
367258882Semaste            else
368258882Semaste                m_exit_description.clear();
369258882Semaste            return true;
370258882Semaste        }
371258882Semaste
372258882Semaste        //----------------------------------------------------------------------
373258882Semaste        // Access to threads
374258882Semaste        //----------------------------------------------------------------------
375258882Semaste        lldb::NativeThreadProtocolSP
376258882Semaste        GetThreadAtIndex (uint32_t idx)
377258882Semaste        {
378258882Semaste            Mutex::Locker locker(m_threads_mutex);
379258882Semaste            if (idx < m_threads.size())
380258882Semaste                return m_threads[idx];
381258882Semaste            return lldb::NativeThreadProtocolSP();
382258882Semaste        }
383258882Semaste
384258882Semaste        lldb::NativeThreadProtocolSP
385258882Semaste        GetThreadByID (lldb::tid_t tid)
386258882Semaste        {
387258882Semaste            Mutex::Locker locker(m_threads_mutex);
388258882Semaste            for (auto thread_sp : m_threads)
389258882Semaste            {
390258882Semaste                if (thread_sp->GetID() == tid)
391258882Semaste                    return thread_sp;
392258882Semaste            }
393258882Semaste            return lldb::NativeThreadProtocolSP();
394258882Semaste        }
395258882Semaste
396258882Semaste    protected:
397258882Semaste        lldb::pid_t m_pid;
398258882Semaste        std::vector<lldb::NativeThreadProtocolSP> m_threads;
399258882Semaste        mutable Mutex m_threads_mutex;
400258882Semaste        lldb::StateType m_state;
401258882Semaste        int m_exit_status;
402258882Semaste        std::string m_exit_description;
403258882Semaste    };
404258882Semaste
405258882Semaste}
406258882Semaste#endif // #ifndef liblldb_Debug_h_
407