remote_gdb.hh revision 13575:aafa2c83ab3c
12SN/A/* 21762SN/A * Copyright (c) 2018 ARM Limited 32SN/A * 42SN/A * The license below extends only to copyright in the software and shall 52SN/A * not be construed as granting a license to any other intellectual 62SN/A * property including but not limited to intellectual property relating 72SN/A * to a hardware implementation of the functionality of the software 82SN/A * licensed hereunder. You may use the software subject to the license 92SN/A * terms below provided that you ensure that this notice is replicated 102SN/A * unmodified and in its entirety in all distributions of the software, 112SN/A * modified or unmodified, in source code or in binary form. 122SN/A * 132SN/A * Copyright 2015 LabWare 142SN/A * Copyright 2014 Google, Inc. 152SN/A * Copyright (c) 2002-2005 The Regents of The University of Michigan 162SN/A * All rights reserved. 172SN/A * 182SN/A * Redistribution and use in source and binary forms, with or without 192SN/A * modification, are permitted provided that the following conditions are 202SN/A * met: redistributions of source code must retain the above copyright 212SN/A * notice, this list of conditions and the following disclaimer; 222SN/A * redistributions in binary form must reproduce the above copyright 232SN/A * notice, this list of conditions and the following disclaimer in the 242SN/A * documentation and/or other materials provided with the distribution; 252SN/A * neither the name of the copyright holders nor the names of its 262SN/A * contributors may be used to endorse or promote products derived from 272665Ssaidi@eecs.umich.edu * this software without specific prior written permission. 282665Ssaidi@eecs.umich.edu * 292665Ssaidi@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 302SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 312SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 3211793Sbrandon.potter@amd.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 3311793Sbrandon.potter@amd.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 3411793Sbrandon.potter@amd.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 358229Snate@binkert.org * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 368229Snate@binkert.org * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 378229Snate@binkert.org * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 3811354SCurtis.Dunham@arm.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 398229Snate@binkert.org * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 408229Snate@binkert.org * 412SN/A * Authors: Nathan Binkert 422SN/A * Boris Shingarov 432SN/A */ 4411793Sbrandon.potter@amd.com 458229Snate@binkert.org#ifndef __REMOTE_GDB_HH__ 469538Satgutier@umich.edu#define __REMOTE_GDB_HH__ 478229Snate@binkert.org 488229Snate@binkert.org#include <sys/signal.h> 498229Snate@binkert.org 508229Snate@binkert.org#include <exception> 518706Sandreas.hansson@arm.com#include <map> 522420SN/A#include <string> 532SN/A 542SN/A#include "arch/types.hh" 5510880SCurtis.Dunham@arm.com#include "base/intmath.hh" 56360SN/A#include "base/pollevent.hh" 5711391Sbrandon.potter@amd.com#include "base/socket.hh" 5810880SCurtis.Dunham@arm.com#include "cpu/pc_event.hh" 5911391Sbrandon.potter@amd.com 6010422Sandreas.hansson@arm.comclass System; 6112SN/Aclass ThreadContext; 6212SN/A 632SN/Aclass BaseRemoteGDB; 642SN/Aclass HardBreakpoint; 652SN/A 662SN/A/** 6711391Sbrandon.potter@amd.com * Concrete subclasses of this abstract class represent how the 6811391Sbrandon.potter@amd.com * register values are transmitted on the wire. Usually each 6911391Sbrandon.potter@amd.com * architecture should define one subclass, but there can be more 7011391Sbrandon.potter@amd.com * if there is more than one possible wire format. For example, 7112SN/A * ARM defines both AArch32GdbRegCache and AArch64GdbRegCache. 722SN/A */ 732SN/Aclass BaseGdbRegCache 742420SN/A{ 7511391Sbrandon.potter@amd.com public: 7611391Sbrandon.potter@amd.com 772420SN/A /** 782420SN/A * Return the pointer to the raw bytes buffer containing the 7911391Sbrandon.potter@amd.com * register values. Each byte of this buffer is literally 802420SN/A * encoded as two hex digits in the g or G RSP packet. 8111391Sbrandon.potter@amd.com */ 822420SN/A virtual char *data() const = 0; 832420SN/A 842420SN/A /** 8511391Sbrandon.potter@amd.com * Return the size of the raw buffer, in bytes 862420SN/A * (i.e., half of the number of digits in the g/G packet). 872420SN/A */ 882420SN/A virtual size_t size() const = 0; 892420SN/A 902420SN/A /** 912420SN/A * Fill the raw buffer from the registers in the ThreadContext. 922420SN/A */ 9311391Sbrandon.potter@amd.com virtual void getRegs(ThreadContext*) = 0; 942420SN/A 9511391Sbrandon.potter@amd.com /** 9611391Sbrandon.potter@amd.com * Set the ThreadContext's registers from the values 9711391Sbrandon.potter@amd.com * in the raw buffer. 982SN/A */ 992SN/A virtual void setRegs(ThreadContext*) const = 0; 10011354SCurtis.Dunham@arm.com 10111354SCurtis.Dunham@arm.com /** 10211354SCurtis.Dunham@arm.com * Return the name to use in places like DPRINTF. 10311354SCurtis.Dunham@arm.com * Having each concrete superclass redefine this member 10411354SCurtis.Dunham@arm.com * is useful in situations where the class of the regCache 10511354SCurtis.Dunham@arm.com * can change on the fly. 10611354SCurtis.Dunham@arm.com */ 10711354SCurtis.Dunham@arm.com virtual const std::string name() const = 0; 10811354SCurtis.Dunham@arm.com 10911354SCurtis.Dunham@arm.com BaseGdbRegCache(BaseRemoteGDB *g) : gdb(g) 11011354SCurtis.Dunham@arm.com {} 11111354SCurtis.Dunham@arm.com virtual ~BaseGdbRegCache() 11211354SCurtis.Dunham@arm.com {} 11311354SCurtis.Dunham@arm.com 11411354SCurtis.Dunham@arm.com protected: 11511354SCurtis.Dunham@arm.com BaseRemoteGDB *gdb; 11611354SCurtis.Dunham@arm.com}; 11711354SCurtis.Dunham@arm.com 11811354SCurtis.Dunham@arm.comclass BaseRemoteGDB 11911354SCurtis.Dunham@arm.com{ 12011354SCurtis.Dunham@arm.com friend class HardBreakpoint; 12111354SCurtis.Dunham@arm.com public: 12211354SCurtis.Dunham@arm.com 12311354SCurtis.Dunham@arm.com /* 12411354SCurtis.Dunham@arm.com * Interface to other parts of the simulator. 12511354SCurtis.Dunham@arm.com */ 12611354SCurtis.Dunham@arm.com BaseRemoteGDB(System *system, ThreadContext *context, int _port); 12711354SCurtis.Dunham@arm.com virtual ~BaseRemoteGDB(); 12811354SCurtis.Dunham@arm.com 12911354SCurtis.Dunham@arm.com std::string name(); 13011354SCurtis.Dunham@arm.com 13111354SCurtis.Dunham@arm.com void listen(); 13211354SCurtis.Dunham@arm.com void connect(); 13311354SCurtis.Dunham@arm.com 13411354SCurtis.Dunham@arm.com int port() const; 13511354SCurtis.Dunham@arm.com 13611354SCurtis.Dunham@arm.com void attach(int fd); 13711354SCurtis.Dunham@arm.com void detach(); 13811354SCurtis.Dunham@arm.com bool isAttached() { return attached; } 13911354SCurtis.Dunham@arm.com 14011354SCurtis.Dunham@arm.com void replaceThreadContext(ThreadContext *_tc) { tc = _tc; } 14111354SCurtis.Dunham@arm.com 14211354SCurtis.Dunham@arm.com bool trap(int type); 14311354SCurtis.Dunham@arm.com bool breakpoint() { return trap(SIGTRAP); } 14411354SCurtis.Dunham@arm.com 14511354SCurtis.Dunham@arm.com private: 14611354SCurtis.Dunham@arm.com /* 14711354SCurtis.Dunham@arm.com * Connection to the external GDB. 14811354SCurtis.Dunham@arm.com */ 14911354SCurtis.Dunham@arm.com void incomingData(int revent); 15011354SCurtis.Dunham@arm.com void connectWrapper(int revent) { connect(); } 15111354SCurtis.Dunham@arm.com 15211354SCurtis.Dunham@arm.com template <void (BaseRemoteGDB::*F)(int revent)> 15311354SCurtis.Dunham@arm.com class SocketEvent : public PollEvent 15411354SCurtis.Dunham@arm.com { 15512SN/A protected: 15612SN/A BaseRemoteGDB *gdb; 1573584Ssaidi@eecs.umich.edu 1582SN/A public: 15912SN/A SocketEvent(BaseRemoteGDB *gdb, int fd, int e) : 16012SN/A PollEvent(fd, e), gdb(gdb) 16112SN/A {} 16212SN/A 1632SN/A void process(int revent) { (gdb->*F)(revent); } 1642SN/A }; 16511354SCurtis.Dunham@arm.com 16611354SCurtis.Dunham@arm.com typedef SocketEvent<&BaseRemoteGDB::connectWrapper> ConnectEvent; 16711354SCurtis.Dunham@arm.com typedef SocketEvent<&BaseRemoteGDB::incomingData> DataEvent; 16811354SCurtis.Dunham@arm.com 16911354SCurtis.Dunham@arm.com friend ConnectEvent; 17011354SCurtis.Dunham@arm.com friend DataEvent; 17111354SCurtis.Dunham@arm.com 17211354SCurtis.Dunham@arm.com ConnectEvent *connectEvent; 17312SN/A DataEvent *dataEvent; 17410422Sandreas.hansson@arm.com 17511354SCurtis.Dunham@arm.com ListenSocket listener; 17611354SCurtis.Dunham@arm.com int _port; 17711354SCurtis.Dunham@arm.com 17812SN/A // The socket commands come in through. 17912SN/A int fd; 18011391Sbrandon.potter@amd.com 18111391Sbrandon.potter@amd.com // Transfer data to/from GDB. 18210880SCurtis.Dunham@arm.com uint8_t getbyte(); 18311354SCurtis.Dunham@arm.com void putbyte(uint8_t b); 18411391Sbrandon.potter@amd.com 18512SN/A void recv(std::vector<char> &bp); 1862SN/A void send(const char *data); 1872SN/A 18811391Sbrandon.potter@amd.com /* 1892SN/A * Simulator side debugger state. 19012SN/A */ 19111391Sbrandon.potter@amd.com bool active; 19211391Sbrandon.potter@amd.com bool attached; 1932SN/A 1942SN/A System *sys; 19511391Sbrandon.potter@amd.com ThreadContext *tc; 19611391Sbrandon.potter@amd.com 1972SN/A BaseGdbRegCache *regCachePtr; 1982SN/A 19911391Sbrandon.potter@amd.com class TrapEvent : public Event 20011391Sbrandon.potter@amd.com { 2012SN/A protected: 2022SN/A int _type; 20311391Sbrandon.potter@amd.com BaseRemoteGDB *gdb; 20411391Sbrandon.potter@amd.com 2059538Satgutier@umich.edu public: 2069538Satgutier@umich.edu TrapEvent(BaseRemoteGDB *g) : gdb(g) 2073584Ssaidi@eecs.umich.edu {} 20811391Sbrandon.potter@amd.com 2093584Ssaidi@eecs.umich.edu void type(int t) { _type = t; } 21012SN/A void process() { gdb->trap(_type); } 21111391Sbrandon.potter@amd.com } trapEvent; 21212SN/A 2132SN/A /* 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