1 : /*
2 : * Copyright 2010 The Native Client Authors. All rights reserved.
3 : * Use of this source code is governed by a BSD-style license that can
4 : * be found in the LICENSE file.
5 : */
6 :
7 :
8 : // This module provides interfaces for accessing the debugging state of
9 : // the target. The target can use either the thread that took the
10 : // exception or run in it's own thread. To respond to the host, the
11 : // application must call the run function with a valid Transport
12 : // which will then be polled for commands. The target will return
13 : // from Run when the host disconnects, or requests a continue.
14 : //
15 : // The object is protected by a mutex, so that it is legal to track or
16 : // ignore threads as an exception takes place.
17 : //
18 : // The Run function expects that all threads of interest are stopped
19 : // with the Step flag cleared before Run is called. It is expected that
20 : // and that all threads are updated with thier modified contexts and
21 : // restarted when the target returns from Run.
22 :
23 : #ifndef SRC_TRUSTED_GDB_RSP_TARGET_H_
24 : #define SRC_TRUSTED_GDB_RSP_TARGET_H_ 1
25 :
26 : #include <map>
27 : #include <string>
28 :
29 : #include "native_client/src/trusted/gdb_rsp/util.h"
30 :
31 : #include "native_client/src/trusted/port/event.h"
32 : #include "native_client/src/trusted/port/platform.h"
33 : #include "native_client/src/trusted/port/mutex.h"
34 : #include "native_client/src/trusted/port/thread.h"
35 :
36 : namespace gdb_rsp {
37 :
38 : class Abi;
39 : class Packet;
40 : class Session;
41 :
42 : class Target {
43 : public:
44 : enum ErrDef {
45 : NONE = 0,
46 : BAD_FORMAT = 1,
47 : BAD_ARGS = 2,
48 : FAILED = 3
49 : };
50 :
51 : enum State {
52 : UNINIT = 0,
53 : RUNNING = 1,
54 : STOPPED = 2
55 : };
56 :
57 : typedef ErrDef (*QFunc_t)(Target *, stringvec&, std::string);
58 : typedef std::map<uint32_t, port::IThread*> ThreadMap_t;
59 : typedef std::map<std::string, std::string> PropertyMap_t;
60 : typedef std::map<uint64_t, uint8_t*> BreakMap_t;
61 :
62 : public:
63 : // Contruct a Target object. By default use the native ABI.
64 : explicit Target(const Abi *abi = NULL);
65 : ~Target();
66 :
67 : // Init must be the first function called to correctlty
68 : // build the Target internal structures.
69 : bool Init();
70 :
71 0 : void SetMemoryBase(uint64_t mem_base) { mem_base_ = mem_base; }
72 :
73 : // Add and remove temporary breakpoints. These breakpoints
74 : // must be added just before we start running, and removed
75 : // just before we stop running to prevent the debugger from
76 : // seeing the modified memory.
77 : bool AddTemporaryBreakpoint(uint64_t address);
78 : bool RemoveTemporaryBreakpoints();
79 :
80 : // This function should be called by a tracked thread when it takes
81 : // an exception. It takes sig_start_ to prevent other exceptions
82 : // from signalling thread. If wait is true, it will then block on
83 : // sig_done_ until a continue is issued by the host.
84 : void Signal(uint32_t id, int8_t sig, bool wait);
85 :
86 : // This function will spin on a session, until it closes. If an
87 : // exception is caught, it will signal the exception thread by
88 : // setting sig_done_.
89 : void Run(Session *ses);
90 :
91 : // This function causes the target to track the state
92 : // of the specified thread and make it availible to
93 : // a connected host.
94 : void TrackThread(port::IThread *thread);
95 :
96 : // This function causes the target to stop tracking the
97 : // state of the specified thread, which will no longer
98 : // be visible to the host.
99 : void IgnoreThread(port::IThread *thread);
100 :
101 : protected:
102 : // This function always succeedes, since all errors
103 : // are reported as an error string of "E<##>" where
104 : // the two digit number. The error codes are not
105 : // not documented, so this implementation uses
106 : // ErrDef as errors codes. This function returns
107 : // true a request to continue (or step) is processed.
108 : bool ProcessPacket(Packet *pktIn, Packet *pktOut);
109 :
110 : void Destroy();
111 : void Detach();
112 :
113 : bool GetFirstThreadId(uint32_t *id);
114 : bool GetNextThreadId(uint32_t *id);
115 :
116 : uint32_t GetRegThreadId() const;
117 : uint32_t GetRunThreadId() const;
118 : port::IThread *GetThread(uint32_t id);
119 :
120 : public:
121 : const Abi *abi_;
122 :
123 : // This mutex protects debugging state (threads_, cur_signal, sig_thread_)
124 : port::IMutex *mutex_;
125 :
126 : // This event is signalled when the target is really to process an
127 : // exception. It ensures only one exception is processed at a time.
128 : port::IEvent *sig_start_;
129 :
130 : // This event is signalled when the target done processing an exception.
131 : port::IEvent *sig_done_;
132 :
133 : // This value is set if the exception cather is requesting a continue signal
134 : bool send_done_;
135 :
136 : ThreadMap_t threads_;
137 : ThreadMap_t::const_iterator threadItr_;
138 : BreakMap_t breakMap_;
139 :
140 :
141 : PropertyMap_t properties_;
142 :
143 : uint8_t *ctx_; // Context Scratchpad
144 :
145 : // The current signal and signaling thread data is protected by
146 : // the mutex, and can only be owned by one thread at a time.
147 : // These values should only be written via the "Signal" member,
148 : // which will ensure that a new signal does not overwrite a
149 : // previous signal.
150 : volatile int8_t cur_signal_;
151 : volatile uint32_t sig_thread_;
152 :
153 : uint32_t run_thread_; // Which thread to issue step commands on
154 : uint32_t reg_thread_; // Which thread to issue context (reg) commands on
155 : uint64_t mem_base_;
156 : };
157 :
158 :
159 : } // namespace gdb_rsp
160 :
161 : #endif // SRC_TRUSTED_GDB_RSP_TARGET_H_
162 :
|