12SN/A/* 213575Sciro.santilli@arm.com * Copyright (c) 2018 ARM Limited 313575Sciro.santilli@arm.com * 413575Sciro.santilli@arm.com * The license below extends only to copyright in the software and shall 513575Sciro.santilli@arm.com * not be construed as granting a license to any other intellectual 613575Sciro.santilli@arm.com * property including but not limited to intellectual property relating 713575Sciro.santilli@arm.com * to a hardware implementation of the functionality of the software 813575Sciro.santilli@arm.com * licensed hereunder. You may use the software subject to the license 913575Sciro.santilli@arm.com * terms below provided that you ensure that this notice is replicated 1013575Sciro.santilli@arm.com * unmodified and in its entirety in all distributions of the software, 1113575Sciro.santilli@arm.com * modified or unmodified, in source code or in binary form. 1213575Sciro.santilli@arm.com * 1311274Sshingarov@labware.com * Copyright 2015 LabWare 1410595Sgabeblack@google.com * Copyright 2014 Google, Inc. 151762SN/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 272SN/A * this software without specific prior written permission. 282SN/A * 292SN/A * 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 322SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 332SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 342SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 352SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 362SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 372SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 382SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 392SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 402665Ssaidi@eecs.umich.edu * 412665Ssaidi@eecs.umich.edu * Authors: Nathan Binkert 4211274Sshingarov@labware.com * Boris Shingarov 432SN/A */ 442SN/A 452SN/A#ifndef __REMOTE_GDB_HH__ 462SN/A#define __REMOTE_GDB_HH__ 472SN/A 483960Sgblack@eecs.umich.edu#include <sys/signal.h> 4977SN/A 5012031Sgabeblack@google.com#include <exception> 518229Snate@binkert.org#include <map> 5212031Sgabeblack@google.com#include <string> 538229Snate@binkert.org 542986Sgblack@eecs.umich.edu#include "arch/types.hh" 5510595Sgabeblack@google.com#include "base/intmath.hh" 5656SN/A#include "base/pollevent.hh" 5756SN/A#include "base/socket.hh" 588229Snate@binkert.org#include "cpu/pc_event.hh" 592SN/A 602SN/Aclass System; 612680Sktlim@umich.educlass ThreadContext; 622SN/A 6312449Sgabeblack@google.comclass BaseRemoteGDB; 6412449Sgabeblack@google.comclass HardBreakpoint; 653536Sgblack@eecs.umich.edu 6612449Sgabeblack@google.com/** 6712449Sgabeblack@google.com * Concrete subclasses of this abstract class represent how the 6812449Sgabeblack@google.com * register values are transmitted on the wire. Usually each 6912449Sgabeblack@google.com * architecture should define one subclass, but there can be more 7012449Sgabeblack@google.com * if there is more than one possible wire format. For example, 7112449Sgabeblack@google.com * ARM defines both AArch32GdbRegCache and AArch64GdbRegCache. 7212449Sgabeblack@google.com */ 7312449Sgabeblack@google.comclass BaseGdbRegCache 742SN/A{ 7512031Sgabeblack@google.com public: 7612031Sgabeblack@google.com 7712449Sgabeblack@google.com /** 7812449Sgabeblack@google.com * Return the pointer to the raw bytes buffer containing the 7912449Sgabeblack@google.com * register values. Each byte of this buffer is literally 8012449Sgabeblack@google.com * encoded as two hex digits in the g or G RSP packet. 8112449Sgabeblack@google.com */ 8212449Sgabeblack@google.com virtual char *data() const = 0; 8312031Sgabeblack@google.com 8412449Sgabeblack@google.com /** 8512449Sgabeblack@google.com * Return the size of the raw buffer, in bytes 8612449Sgabeblack@google.com * (i.e., half of the number of digits in the g/G packet). 8712449Sgabeblack@google.com */ 8812449Sgabeblack@google.com virtual size_t size() const = 0; 8912031Sgabeblack@google.com 9012449Sgabeblack@google.com /** 9112449Sgabeblack@google.com * Fill the raw buffer from the registers in the ThreadContext. 9212449Sgabeblack@google.com */ 9312449Sgabeblack@google.com virtual void getRegs(ThreadContext*) = 0; 9412449Sgabeblack@google.com 9512449Sgabeblack@google.com /** 9612449Sgabeblack@google.com * Set the ThreadContext's registers from the values 9712449Sgabeblack@google.com * in the raw buffer. 9812449Sgabeblack@google.com */ 9912449Sgabeblack@google.com virtual void setRegs(ThreadContext*) const = 0; 10012449Sgabeblack@google.com 10112449Sgabeblack@google.com /** 10212449Sgabeblack@google.com * Return the name to use in places like DPRINTF. 10312449Sgabeblack@google.com * Having each concrete superclass redefine this member 10412449Sgabeblack@google.com * is useful in situations where the class of the regCache 10512449Sgabeblack@google.com * can change on the fly. 10612449Sgabeblack@google.com */ 10712449Sgabeblack@google.com virtual const std::string name() const = 0; 10812449Sgabeblack@google.com 10912449Sgabeblack@google.com BaseGdbRegCache(BaseRemoteGDB *g) : gdb(g) 11012031Sgabeblack@google.com {} 11112449Sgabeblack@google.com virtual ~BaseGdbRegCache() 11212449Sgabeblack@google.com {} 11312449Sgabeblack@google.com 11412449Sgabeblack@google.com protected: 11512449Sgabeblack@google.com BaseRemoteGDB *gdb; 1163536Sgblack@eecs.umich.edu}; 1173536Sgblack@eecs.umich.edu 1183536Sgblack@eecs.umich.educlass BaseRemoteGDB 1193536Sgblack@eecs.umich.edu{ 12012449Sgabeblack@google.com friend class HardBreakpoint; 12112449Sgabeblack@google.com public: 12212449Sgabeblack@google.com 12312449Sgabeblack@google.com /* 12412449Sgabeblack@google.com * Interface to other parts of the simulator. 12512449Sgabeblack@google.com */ 12612449Sgabeblack@google.com BaseRemoteGDB(System *system, ThreadContext *context, int _port); 12712449Sgabeblack@google.com virtual ~BaseRemoteGDB(); 12812449Sgabeblack@google.com 12912449Sgabeblack@google.com std::string name(); 13012449Sgabeblack@google.com 13112449Sgabeblack@google.com void listen(); 13212449Sgabeblack@google.com void connect(); 13312449Sgabeblack@google.com 13412449Sgabeblack@google.com int port() const; 13512449Sgabeblack@google.com 13612449Sgabeblack@google.com void attach(int fd); 13712449Sgabeblack@google.com void detach(); 13812449Sgabeblack@google.com bool isAttached() { return attached; } 13912449Sgabeblack@google.com 14012449Sgabeblack@google.com void replaceThreadContext(ThreadContext *_tc) { tc = _tc; } 14112449Sgabeblack@google.com 14212449Sgabeblack@google.com bool trap(int type); 14312449Sgabeblack@google.com bool breakpoint() { return trap(SIGTRAP); } 14412449Sgabeblack@google.com 1451910SN/A private: 14612449Sgabeblack@google.com /* 14712449Sgabeblack@google.com * Connection to the external GDB. 14812449Sgabeblack@google.com */ 14912449Sgabeblack@google.com void incomingData(int revent); 15012449Sgabeblack@google.com void connectWrapper(int revent) { connect(); } 1511910SN/A 15212449Sgabeblack@google.com template <void (BaseRemoteGDB::*F)(int revent)> 15312449Sgabeblack@google.com class SocketEvent : public PollEvent 15412031Sgabeblack@google.com { 15512449Sgabeblack@google.com protected: 15612449Sgabeblack@google.com BaseRemoteGDB *gdb; 15712449Sgabeblack@google.com 15812449Sgabeblack@google.com public: 15912449Sgabeblack@google.com SocketEvent(BaseRemoteGDB *gdb, int fd, int e) : 16012449Sgabeblack@google.com PollEvent(fd, e), gdb(gdb) 16112031Sgabeblack@google.com {} 16212449Sgabeblack@google.com 16312449Sgabeblack@google.com void process(int revent) { (gdb->*F)(revent); } 16412031Sgabeblack@google.com }; 16512449Sgabeblack@google.com 16612449Sgabeblack@google.com typedef SocketEvent<&BaseRemoteGDB::connectWrapper> ConnectEvent; 16712449Sgabeblack@google.com typedef SocketEvent<&BaseRemoteGDB::incomingData> DataEvent; 16812449Sgabeblack@google.com 16912449Sgabeblack@google.com friend ConnectEvent; 17012449Sgabeblack@google.com friend DataEvent; 17112449Sgabeblack@google.com 17212449Sgabeblack@google.com ConnectEvent *connectEvent; 17312449Sgabeblack@google.com DataEvent *dataEvent; 17412449Sgabeblack@google.com 17512449Sgabeblack@google.com ListenSocket listener; 17612449Sgabeblack@google.com int _port; 17712449Sgabeblack@google.com 17812449Sgabeblack@google.com // The socket commands come in through. 17912449Sgabeblack@google.com int fd; 18012449Sgabeblack@google.com 18112449Sgabeblack@google.com // Transfer data to/from GDB. 18212449Sgabeblack@google.com uint8_t getbyte(); 18312449Sgabeblack@google.com void putbyte(uint8_t b); 18412449Sgabeblack@google.com 18513470Sciro.santilli@arm.com void recv(std::vector<char> &bp); 18612449Sgabeblack@google.com void send(const char *data); 18712449Sgabeblack@google.com 18812449Sgabeblack@google.com /* 18912449Sgabeblack@google.com * Simulator side debugger state. 19012449Sgabeblack@google.com */ 19112449Sgabeblack@google.com bool active; 19212449Sgabeblack@google.com bool attached; 19312449Sgabeblack@google.com 19412449Sgabeblack@google.com System *sys; 19512449Sgabeblack@google.com ThreadContext *tc; 19612449Sgabeblack@google.com 19712449Sgabeblack@google.com BaseGdbRegCache *regCachePtr; 19812449Sgabeblack@google.com 19912449Sgabeblack@google.com class TrapEvent : public Event 20012031Sgabeblack@google.com { 20112449Sgabeblack@google.com protected: 20212449Sgabeblack@google.com int _type; 20312449Sgabeblack@google.com BaseRemoteGDB *gdb; 20412449Sgabeblack@google.com 20512449Sgabeblack@google.com public: 20612449Sgabeblack@google.com TrapEvent(BaseRemoteGDB *g) : gdb(g) 20712031Sgabeblack@google.com {} 20812449Sgabeblack@google.com 20912449Sgabeblack@google.com void type(int t) { _type = t; } 21012449Sgabeblack@google.com void process() { gdb->trap(_type); } 21112449Sgabeblack@google.com } trapEvent; 21212449Sgabeblack@google.com 21312449Sgabeblack@google.com /* 21412449Sgabeblack@google.com * The interface to the simulated system. 21512449Sgabeblack@google.com */ 21612449Sgabeblack@google.com // Machine memory. 21712449Sgabeblack@google.com bool read(Addr addr, size_t size, char *data); 21812449Sgabeblack@google.com bool write(Addr addr, size_t size, const char *data); 21912449Sgabeblack@google.com 22012449Sgabeblack@google.com template <class T> T read(Addr addr); 22112449Sgabeblack@google.com template <class T> void write(Addr addr, T data); 22212449Sgabeblack@google.com 22312449Sgabeblack@google.com // Single step. 22412449Sgabeblack@google.com void singleStep(); 22512449Sgabeblack@google.com EventWrapper<BaseRemoteGDB, &BaseRemoteGDB::singleStep> singleStepEvent; 22612449Sgabeblack@google.com 22712449Sgabeblack@google.com void clearSingleStep(); 22812449Sgabeblack@google.com void setSingleStep(); 22912449Sgabeblack@google.com 23012449Sgabeblack@google.com /// Schedule an event which will be triggered "delta" instructions later. 23112449Sgabeblack@google.com void scheduleInstCommitEvent(Event *ev, int delta); 23212449Sgabeblack@google.com /// Deschedule an instruction count based event. 23312449Sgabeblack@google.com void descheduleInstCommitEvent(Event *ev); 23412449Sgabeblack@google.com 23512449Sgabeblack@google.com // Breakpoints. 23612449Sgabeblack@google.com void insertSoftBreak(Addr addr, size_t len); 23712449Sgabeblack@google.com void removeSoftBreak(Addr addr, size_t len); 23812449Sgabeblack@google.com void insertHardBreak(Addr addr, size_t len); 23912449Sgabeblack@google.com void removeHardBreak(Addr addr, size_t len); 24012449Sgabeblack@google.com 24112449Sgabeblack@google.com void clearTempBreakpoint(Addr &bkpt); 24212449Sgabeblack@google.com void setTempBreakpoint(Addr bkpt); 24312449Sgabeblack@google.com 24412449Sgabeblack@google.com /* 24512449Sgabeblack@google.com * GDB commands. 24612449Sgabeblack@google.com */ 24712449Sgabeblack@google.com struct GdbCommand 24812449Sgabeblack@google.com { 24912449Sgabeblack@google.com public: 25012449Sgabeblack@google.com struct Context 25112449Sgabeblack@google.com { 25212449Sgabeblack@google.com const GdbCommand *cmd; 25312449Sgabeblack@google.com char cmd_byte; 25412449Sgabeblack@google.com int type; 25512449Sgabeblack@google.com char *data; 25612449Sgabeblack@google.com int len; 25712449Sgabeblack@google.com }; 25812449Sgabeblack@google.com 25912449Sgabeblack@google.com typedef bool (BaseRemoteGDB::*Func)(Context &ctx); 26012449Sgabeblack@google.com 26112449Sgabeblack@google.com const char * const name; 26212449Sgabeblack@google.com const Func func; 26312449Sgabeblack@google.com 26412449Sgabeblack@google.com GdbCommand(const char *_name, Func _func) : name(_name), func(_func) {} 26512031Sgabeblack@google.com }; 26612031Sgabeblack@google.com 26712031Sgabeblack@google.com static std::map<char, GdbCommand> command_map; 26812031Sgabeblack@google.com 26912031Sgabeblack@google.com bool cmd_unsupported(GdbCommand::Context &ctx); 27012031Sgabeblack@google.com 27112031Sgabeblack@google.com bool cmd_signal(GdbCommand::Context &ctx); 27212031Sgabeblack@google.com bool cmd_cont(GdbCommand::Context &ctx); 27312031Sgabeblack@google.com bool cmd_async_cont(GdbCommand::Context &ctx); 27412031Sgabeblack@google.com bool cmd_detach(GdbCommand::Context &ctx); 27512031Sgabeblack@google.com bool cmd_reg_r(GdbCommand::Context &ctx); 27612031Sgabeblack@google.com bool cmd_reg_w(GdbCommand::Context &ctx); 27712031Sgabeblack@google.com bool cmd_set_thread(GdbCommand::Context &ctx); 27812031Sgabeblack@google.com bool cmd_mem_r(GdbCommand::Context &ctx); 27912031Sgabeblack@google.com bool cmd_mem_w(GdbCommand::Context &ctx); 28012031Sgabeblack@google.com bool cmd_query_var(GdbCommand::Context &ctx); 28112031Sgabeblack@google.com bool cmd_step(GdbCommand::Context &ctx); 28212031Sgabeblack@google.com bool cmd_async_step(GdbCommand::Context &ctx); 28312031Sgabeblack@google.com bool cmd_clr_hw_bkpt(GdbCommand::Context &ctx); 28412031Sgabeblack@google.com bool cmd_set_hw_bkpt(GdbCommand::Context &ctx); 2853536Sgblack@eecs.umich.edu 2862SN/A protected: 28712449Sgabeblack@google.com ThreadContext *context() { return tc; } 28812449Sgabeblack@google.com System *system() { return sys; } 2892SN/A 29013575Sciro.santilli@arm.com void encodeBinaryData(const std::string &unencoded, 29113575Sciro.santilli@arm.com std::string &encoded) const; 29213575Sciro.santilli@arm.com 29313575Sciro.santilli@arm.com void encodeXferResponse(const std::string &unencoded, 29413575Sciro.santilli@arm.com std::string &encoded, size_t offset, size_t unencoded_length) const; 29513575Sciro.santilli@arm.com 29612449Sgabeblack@google.com // To be implemented by subclasses. 29712449Sgabeblack@google.com virtual bool checkBpLen(size_t len); 2982SN/A 29911274Sshingarov@labware.com virtual BaseGdbRegCache *gdbRegs() = 0; 3002SN/A 3013536Sgblack@eecs.umich.edu virtual bool acc(Addr addr, size_t len) = 0; 30213575Sciro.santilli@arm.com 30313575Sciro.santilli@arm.com virtual std::vector<std::string> availableFeatures() const; 30413575Sciro.santilli@arm.com 30513575Sciro.santilli@arm.com /** 30613575Sciro.santilli@arm.com * Get an XML target description. 30713575Sciro.santilli@arm.com * 30813575Sciro.santilli@arm.com * @param[in] annex the XML filename 30913575Sciro.santilli@arm.com * @param[out] output set to the decoded XML 31013575Sciro.santilli@arm.com * @return true if the given annex was found 31113575Sciro.santilli@arm.com */ 31213575Sciro.santilli@arm.com virtual bool getXferFeaturesRead(const std::string &annex, 31313575Sciro.santilli@arm.com std::string &output); 3142SN/A}; 3152SN/A 3162SN/Atemplate <class T> 3172SN/Ainline T 3183536Sgblack@eecs.umich.eduBaseRemoteGDB::read(Addr addr) 3192SN/A{ 3202SN/A T temp; 3212SN/A read(addr, sizeof(T), (char *)&temp); 3222SN/A return temp; 3232SN/A} 3242SN/A 3252SN/Atemplate <class T> 3262SN/Ainline void 3273536Sgblack@eecs.umich.eduBaseRemoteGDB::write(Addr addr, T data) 3282SN/A{ 32912449Sgabeblack@google.com write(addr, sizeof(T), (const char *)&data); 33012449Sgabeblack@google.com} 3312SN/A 3322SN/A#endif /* __REMOTE_GDB_H__ */ 333