]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/plr/server/src/gdb_stub/gdbserver
update
[l4.git] / l4 / pkg / plr / server / src / gdb_stub / gdbserver
1 // vim: ft=cpp
2
3 /*
4  * gdb_stub/gdbserver --
5  *
6  *     Definition of the GDB server stub
7  *
8  * (c) 2011-2013 Björn Döbel <doebel@os.inf.tu-dresden.de>,
9  *     economic rights: Technische Universität Dresden (Germany)
10  * This file is part of TUD:OS and distributed under the terms of the
11  * GNU General Public License 2.
12  * Please see the COPYING-GPL-2 file for details.
13  */
14
15 #pragma once
16
17 #include "../app"
18 #include "../fault_observers"
19 #include "connection"
20
21 namespace Romain {
22
23         enum GDBRegisters {
24                 ax, cx, dx, bx,
25                 sp, bp, si, di,
26                 ip, flags, nuffin,
27                 ss, ds, es, fs, gs,
28         };
29
30         enum GDBSpecialCommands {
31                 NoCmd,
32                 GDBInterrupt = 3,
33                 GDBAck = '+',
34                 GDBRetry = '-',
35                 GDBCmdStart = '$',
36         };
37
38
39         class GDBServerObserver : public Observer
40         {
41                 DECLARE_OBSERVER("gdb");
42
43                 private:
44
45                 Connection *_con;
46                 // XXX: platform_thread?
47                 pthread_t  _thread;              // the pthread we use for receiving
48
49                 bool       _connected;           // flag if we have a connection yet
50                 bool       _ack_mode;            // are we in ack mode?
51                 bool       _await_ack;           // expecting and ack?
52                 char     * _bufptr;              // pointer to last cmd found in packetbuf
53                 char       _inbuf[1024];         // buffer for incoming packet data
54                 char       _outbuf[1024];        // buffer for outgoing packet data
55                 char       _last_cmd[64];        // last command (in case we need to retry)
56
57                 L4vcpu::Vcpu       _saved_vcpu;     // saved VCPU TODO: per-thread
58                 //l4_utcb_t          saved_utcb;    // saved UTCB TODO: per-thread
59                 Romain::App_model const * _app_model;  // saved APP model
60                 Romain::App_thread      * _notifyThread; // last thread that entered the debugger
61
62                 // XXX: platform_signal_type ?
63                 sem_t     _app_wait_signal;    // sem to be polled by notify() until gdb sends C or S
64                 sem_t     _gdb_wait_signal;    // sem to be polled by gdb until app finished exec of S
65
66                 bool      _want_halt;          // do we want to halt our threads?
67                 bool      _singlestep;         // single-stepping mode?
68
69                 public:
70                 GDBServerObserver(Connection* con);
71
72                 virtual ~GDBServerObserver();
73
74                 void notify_and_wait(sem_t *toSend, sem_t *toWait)
75                 {
76                         int r = sem_post(toSend);
77                         _check(r != 0, "sem_post");
78                         r = sem_wait(toWait);
79                         _check(r != 0, "sem_wait");
80                 }
81
82
83                 void notify_connect()
84                 {
85                         _connected = true;
86                         notify_and_wait(&_app_wait_signal, &_gdb_wait_signal);
87                 }
88
89
90                 char *buffer() const { return (char * const)_inbuf; }
91                 unsigned maxbuffer() const { return 1024; }
92                 Connection * connection() const { return _con; }
93
94                 void disconnect()
95                 {
96                         _con->disconnect();
97                         _ack_mode = true;
98                         memset(_inbuf, 0, sizeof(_inbuf));
99                         memset(_outbuf, 0, sizeof(_outbuf));
100                 }
101
102                 /*
103                  * VCPU store/restore
104                  *
105                  * XXX: Udo optimization: only copy the stuff that has been changed instead
106                  *      of everything, because most commands will not ever modify the UTCB?
107                  */
108                 void save_vcpu(Romain::App_thread *t)
109                 {
110                         _notifyThread = t;
111                         memcpy(&_saved_vcpu, t->vcpu(), sizeof(*t->vcpu()));
112                         //memcpy(&saved_utcb, t->vcpu_utcb(), sizeof(*t->vcpu_utcb()));
113                 }
114
115                 void restore_vcpu(Romain::App_thread *t)
116                 {
117                         memcpy(t->vcpu(), &_saved_vcpu, sizeof(*t->vcpu()));
118                         //memcpy(t->vcpu_utcb(), &saved_utcb, sizeof(*t->vcpu_utcb()));
119                 }
120
121
122                 /*
123                  * Determine which signal to return to a waiting gdb client
124                  */
125                 void signal_return(Romain::App_thread *t = 0);
126
127                 /*
128                  * Generic command handlers
129                  */
130                 int handle_cmd();
131                 bool next_cmd();
132
133                 /*
134                  * Packet handling functions
135                  */
136                 bool checksum_cmd(char const *, char const **);
137                 void append_checksum(char *ptr);
138
139                 /*
140                  * Command implementations
141                  */
142                 void gdb_continue(char const* cmd, bool withSignal);
143                 void gdb_get_registers(char const * const);
144                 void gdb_select_thread(char const * const cmd);
145                 void gdb_dump_mem(char const * const cmd);
146                 void gdb_query(char const * const query);
147                 void gdb_settings(char const * const cmd);
148                 void gdb_step(char const* cmd, bool withSignal);
149                 void gdb_breakpoint(char const* cmd);
150                 void gdb_write_mem(char const* cmd, bool binaryData);
151                 void gdb_read_register(char const* cmd);
152                 void gdb_write_register(char const *cmd);
153
154         };
155 }