1/*
2 * Copyright (c) 2018 ARM Limited
3 *
4 * The license below extends only to copyright in the software and shall
5 * not be construed as granting a license to any other intellectual
6 * property including but not limited to intellectual property relating
7 * to a hardware implementation of the functionality of the software
8 * licensed hereunder.  You may use the software subject to the license
9 * terms below provided that you ensure that this notice is replicated
10 * unmodified and in its entirety in all distributions of the software,
11 * modified or unmodified, in source code or in binary form.
12 *
13 * Copyright 2015 LabWare
14 * Copyright 2014 Google, Inc.
15 * Copyright (c) 2002-2005 The Regents of The University of Michigan
16 * All rights reserved.
17 *
18 * Redistribution and use in source and binary forms, with or without
19 * modification, are permitted provided that the following conditions are
20 * met: redistributions of source code must retain the above copyright
21 * notice, this list of conditions and the following disclaimer;
22 * redistributions in binary form must reproduce the above copyright
23 * notice, this list of conditions and the following disclaimer in the
24 * documentation and/or other materials provided with the distribution;
25 * neither the name of the copyright holders nor the names of its
26 * contributors may be used to endorse or promote products derived from
27 * this software without specific prior written permission.
28 *
29 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
30 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
31 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
32 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
33 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
34 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
35 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
36 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
37 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
38 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
39 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
40 *
41 * Authors: Nathan Binkert
42 *          Boris Shingarov
43 */
44
45#ifndef __REMOTE_GDB_HH__
46#define __REMOTE_GDB_HH__
47
48#include <sys/signal.h>
49
50#include <exception>
51#include <map>
52#include <string>
53
54#include "arch/types.hh"
55#include "base/intmath.hh"
56#include "base/pollevent.hh"
57#include "base/socket.hh"
58#include "cpu/pc_event.hh"
59
60class System;
61class ThreadContext;
62
63class BaseRemoteGDB;
64class HardBreakpoint;
65
66/**
67 * Concrete subclasses of this abstract class represent how the
68 * register values are transmitted on the wire.  Usually each
69 * architecture should define one subclass, but there can be more
70 * if there is more than one possible wire format.  For example,
71 * ARM defines both AArch32GdbRegCache and AArch64GdbRegCache.
72 */
73class BaseGdbRegCache
74{
75  public:
76
77    /**
78     * Return the pointer to the raw bytes buffer containing the
79     * register values.  Each byte of this buffer is literally
80     * encoded as two hex digits in the g or G RSP packet.
81     */
82    virtual char *data() const = 0;
83
84    /**
85     * Return the size of the raw buffer, in bytes
86     * (i.e., half of the number of digits in the g/G packet).
87     */
88    virtual size_t size() const = 0;
89
90    /**
91     * Fill the raw buffer from the registers in the ThreadContext.
92     */
93    virtual void getRegs(ThreadContext*) = 0;
94
95    /**
96     * Set the ThreadContext's registers from the values
97     * in the raw buffer.
98     */
99    virtual void setRegs(ThreadContext*) const = 0;
100
101    /**
102     * Return the name to use in places like DPRINTF.
103     * Having each concrete superclass redefine this member
104     * is useful in situations where the class of the regCache
105     * can change on the fly.
106     */
107    virtual const std::string name() const = 0;
108
109    BaseGdbRegCache(BaseRemoteGDB *g) : gdb(g)
110    {}
111    virtual ~BaseGdbRegCache()
112    {}
113
114  protected:
115    BaseRemoteGDB *gdb;
116};
117
118class BaseRemoteGDB
119{
120    friend class HardBreakpoint;
121  public:
122
123    /*
124     * Interface to other parts of the simulator.
125     */
126    BaseRemoteGDB(System *system, ThreadContext *context, int _port);
127    virtual ~BaseRemoteGDB();
128
129    std::string name();
130
131    void listen();
132    void connect();
133
134    int port() const;
135
136    void attach(int fd);
137    void detach();
138    bool isAttached() { return attached; }
139
140    void replaceThreadContext(ThreadContext *_tc) { tc = _tc; }
141
142    bool trap(int type);
143    bool breakpoint() { return trap(SIGTRAP); }
144
145  private:
146    /*
147     * Connection to the external GDB.
148     */
149    void incomingData(int revent);
150    void connectWrapper(int revent) { connect(); }
151
152    template <void (BaseRemoteGDB::*F)(int revent)>
153    class SocketEvent : public PollEvent
154    {
155      protected:
156        BaseRemoteGDB *gdb;
157
158      public:
159        SocketEvent(BaseRemoteGDB *gdb, int fd, int e) :
160            PollEvent(fd, e), gdb(gdb)
161        {}
162
163        void process(int revent) { (gdb->*F)(revent); }
164    };
165
166    typedef SocketEvent<&BaseRemoteGDB::connectWrapper> ConnectEvent;
167    typedef SocketEvent<&BaseRemoteGDB::incomingData> DataEvent;
168
169    friend ConnectEvent;
170    friend DataEvent;
171
172    ConnectEvent *connectEvent;
173    DataEvent *dataEvent;
174
175    ListenSocket listener;
176    int _port;
177
178    // The socket commands come in through.
179    int fd;
180
181    // Transfer data to/from GDB.
182    uint8_t getbyte();
183    void putbyte(uint8_t b);
184
185    void recv(std::vector<char> &bp);
186    void send(const char *data);
187
188    /*
189     * Simulator side debugger state.
190     */
191    bool active;
192    bool attached;
193
194    System *sys;
195    ThreadContext *tc;
196
197    BaseGdbRegCache *regCachePtr;
198
199    class TrapEvent : public Event
200    {
201      protected:
202        int _type;
203        BaseRemoteGDB *gdb;
204
205      public:
206        TrapEvent(BaseRemoteGDB *g) : gdb(g)
207        {}
208
209        void type(int t) { _type = t; }
210        void process() { gdb->trap(_type); }
211    } trapEvent;
212
213    /*
214     * The interface to the simulated system.
215     */
216    // Machine memory.
217    bool read(Addr addr, size_t size, char *data);
218    bool write(Addr addr, size_t size, const char *data);
219
220    template <class T> T read(Addr addr);
221    template <class T> void write(Addr addr, T data);
222
223    // Single step.
224    void singleStep();
225    EventWrapper<BaseRemoteGDB, &BaseRemoteGDB::singleStep> singleStepEvent;
226
227    void clearSingleStep();
228    void setSingleStep();
229
230    /// Schedule an event which will be triggered "delta" instructions later.
231    void scheduleInstCommitEvent(Event *ev, int delta);
232    /// Deschedule an instruction count based event.
233    void descheduleInstCommitEvent(Event *ev);
234
235    // Breakpoints.
236    void insertSoftBreak(Addr addr, size_t len);
237    void removeSoftBreak(Addr addr, size_t len);
238    void insertHardBreak(Addr addr, size_t len);
239    void removeHardBreak(Addr addr, size_t len);
240
241    void clearTempBreakpoint(Addr &bkpt);
242    void setTempBreakpoint(Addr bkpt);
243
244    /*
245     * GDB commands.
246     */
247    struct GdbCommand
248    {
249      public:
250        struct Context
251        {
252            const GdbCommand *cmd;
253            char cmd_byte;
254            int type;
255            char *data;
256            int len;
257        };
258
259        typedef bool (BaseRemoteGDB::*Func)(Context &ctx);
260
261        const char * const name;
262        const Func func;
263
264        GdbCommand(const char *_name, Func _func) : name(_name), func(_func) {}
265    };
266
267    static std::map<char, GdbCommand> command_map;
268
269    bool cmd_unsupported(GdbCommand::Context &ctx);
270
271    bool cmd_signal(GdbCommand::Context &ctx);
272    bool cmd_cont(GdbCommand::Context &ctx);
273    bool cmd_async_cont(GdbCommand::Context &ctx);
274    bool cmd_detach(GdbCommand::Context &ctx);
275    bool cmd_reg_r(GdbCommand::Context &ctx);
276    bool cmd_reg_w(GdbCommand::Context &ctx);
277    bool cmd_set_thread(GdbCommand::Context &ctx);
278    bool cmd_mem_r(GdbCommand::Context &ctx);
279    bool cmd_mem_w(GdbCommand::Context &ctx);
280    bool cmd_query_var(GdbCommand::Context &ctx);
281    bool cmd_step(GdbCommand::Context &ctx);
282    bool cmd_async_step(GdbCommand::Context &ctx);
283    bool cmd_clr_hw_bkpt(GdbCommand::Context &ctx);
284    bool cmd_set_hw_bkpt(GdbCommand::Context &ctx);
285
286  protected:
287    ThreadContext *context() { return tc; }
288    System *system() { return sys; }
289
290    void encodeBinaryData(const std::string &unencoded,
291            std::string &encoded) const;
292
293    void encodeXferResponse(const std::string &unencoded,
294        std::string &encoded, size_t offset, size_t unencoded_length) const;
295
296    // To be implemented by subclasses.
297    virtual bool checkBpLen(size_t len);
298
299    virtual BaseGdbRegCache *gdbRegs() = 0;
300
301    virtual bool acc(Addr addr, size_t len) = 0;
302
303    virtual std::vector<std::string> availableFeatures() const;
304
305    /**
306     * Get an XML target description.
307     *
308     * @param[in] annex the XML filename
309     * @param[out] output set to the decoded XML
310     * @return true if the given annex was found
311     */
312    virtual bool getXferFeaturesRead(const std::string &annex,
313            std::string &output);
314};
315
316template <class T>
317inline T
318BaseRemoteGDB::read(Addr addr)
319{
320    T temp;
321    read(addr, sizeof(T), (char *)&temp);
322    return temp;
323}
324
325template <class T>
326inline void
327BaseRemoteGDB::write(Addr addr, T data)
328{
329    write(addr, sizeof(T), (const char *)&data);
330}
331
332#endif /* __REMOTE_GDB_H__ */
333