remote_gdb.hh revision 3550
12SN/A/* 21762SN/A * Copyright (c) 2002-2005 The Regents of The University of Michigan 32SN/A * All rights reserved. 42SN/A * 52SN/A * Redistribution and use in source and binary forms, with or without 62SN/A * modification, are permitted provided that the following conditions are 72SN/A * met: redistributions of source code must retain the above copyright 82SN/A * notice, this list of conditions and the following disclaimer; 92SN/A * redistributions in binary form must reproduce the above copyright 102SN/A * notice, this list of conditions and the following disclaimer in the 112SN/A * documentation and/or other materials provided with the distribution; 122SN/A * neither the name of the copyright holders nor the names of its 132SN/A * contributors may be used to endorse or promote products derived from 142SN/A * this software without specific prior written permission. 152SN/A * 162SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 172SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 182SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 192SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 202SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 212SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 222SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 232SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 242SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 252SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 262SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 272665Ssaidi@eecs.umich.edu * 282665Ssaidi@eecs.umich.edu * Authors: Nathan Binkert 292SN/A */ 302SN/A 312SN/A#ifndef __REMOTE_GDB_HH__ 322SN/A#define __REMOTE_GDB_HH__ 332SN/A 3477SN/A#include <map> 3577SN/A 362986Sgblack@eecs.umich.edu#include "arch/types.hh" 3756SN/A#include "cpu/pc_event.hh" 3856SN/A#include "base/pollevent.hh" 3956SN/A#include "base/socket.hh" 402SN/A 412SN/Aclass System; 422680Sktlim@umich.educlass ThreadContext; 432SN/Aclass PhysicalMemory; 442SN/A 451910SN/Aclass GDBListener; 463536Sgblack@eecs.umich.edu 473536Sgblack@eecs.umich.eduenum GDBCommands 482SN/A{ 493536Sgblack@eecs.umich.edu GDBSignal = '?', // last signal 503536Sgblack@eecs.umich.edu GDBSetBaud = 'b', // set baud (depracated) 513536Sgblack@eecs.umich.edu GDBSetBreak = 'B', // set breakpoint (depracated) 523536Sgblack@eecs.umich.edu GDBCont = 'c', // resume 533536Sgblack@eecs.umich.edu GDBAsyncCont = 'C', // continue with signal 543536Sgblack@eecs.umich.edu GDBDebug = 'd', // toggle debug flags (deprecated) 553536Sgblack@eecs.umich.edu GDBDetach = 'D', // detach remote gdb 563536Sgblack@eecs.umich.edu GDBRegR = 'g', // read general registers 573536Sgblack@eecs.umich.edu GDBRegW = 'G', // write general registers 583536Sgblack@eecs.umich.edu GDBSetThread = 'H', // set thread 593536Sgblack@eecs.umich.edu GDBCycleStep = 'i', // step a single cycle 603536Sgblack@eecs.umich.edu GDBSigCycleStep = 'I', // signal then cycle step 613536Sgblack@eecs.umich.edu GDBKill = 'k', // kill program 623536Sgblack@eecs.umich.edu GDBMemR = 'm', // read memory 633536Sgblack@eecs.umich.edu GDBMemW = 'M', // write memory 643536Sgblack@eecs.umich.edu GDBReadReg = 'p', // read register 653536Sgblack@eecs.umich.edu GDBSetReg = 'P', // write register 663536Sgblack@eecs.umich.edu GDBQueryVar = 'q', // query variable 673536Sgblack@eecs.umich.edu GDBSetVar = 'Q', // set variable 683536Sgblack@eecs.umich.edu GDBReset = 'r', // reset system. (Deprecated) 693536Sgblack@eecs.umich.edu GDBStep = 's', // step 703536Sgblack@eecs.umich.edu GDBAsyncStep = 'S', // signal and step 713536Sgblack@eecs.umich.edu GDBThreadAlive = 'T', // find out if the thread is alive 723536Sgblack@eecs.umich.edu GDBTargetExit = 'W', // target exited 733536Sgblack@eecs.umich.edu GDBBinaryDload = 'X', // write memory 743536Sgblack@eecs.umich.edu GDBClrHwBkpt = 'z', // remove breakpoint or watchpoint 753536Sgblack@eecs.umich.edu GDBSetHwBkpt = 'Z' // insert breakpoint or watchpoint 763536Sgblack@eecs.umich.edu}; 773536Sgblack@eecs.umich.edu 783536Sgblack@eecs.umich.educonst char GDBStart = '$'; 793536Sgblack@eecs.umich.educonst char GDBEnd = '#'; 803536Sgblack@eecs.umich.educonst char GDBGoodP = '+'; 813536Sgblack@eecs.umich.educonst char GDBBadP = '-'; 823536Sgblack@eecs.umich.edu 833536Sgblack@eecs.umich.educonst int GDBPacketBufLen = 1024; 843536Sgblack@eecs.umich.edu 853536Sgblack@eecs.umich.educlass BaseRemoteGDB 863536Sgblack@eecs.umich.edu{ 871910SN/A private: 881910SN/A friend void debugger(); 891910SN/A friend class GDBListener; 901910SN/A 913536Sgblack@eecs.umich.edu //Helper functions 923536Sgblack@eecs.umich.edu protected: 933536Sgblack@eecs.umich.edu int digit2i(char); 943536Sgblack@eecs.umich.edu char i2digit(int); 953536Sgblack@eecs.umich.edu Addr hex2i(const char **); 963536Sgblack@eecs.umich.edu //Address formats, break types, and gdb commands may change 973536Sgblack@eecs.umich.edu //between architectures, so they're defined as virtual 983536Sgblack@eecs.umich.edu //functions. 993536Sgblack@eecs.umich.edu virtual void mem2hex(void *, const void *, int); 1003536Sgblack@eecs.umich.edu virtual const char * hex2mem(void *, const char *, int); 1013536Sgblack@eecs.umich.edu virtual const char * break_type(char c); 1023536Sgblack@eecs.umich.edu virtual const char * gdb_command(char cmd); 1033536Sgblack@eecs.umich.edu 1042SN/A protected: 1052SN/A class Event : public PollEvent 1062SN/A { 1072SN/A protected: 1083536Sgblack@eecs.umich.edu BaseRemoteGDB *gdb; 1092SN/A 1102SN/A public: 1113536Sgblack@eecs.umich.edu Event(BaseRemoteGDB *g, int fd, int e); 1122SN/A void process(int revent); 1132SN/A }; 1142SN/A 1152SN/A friend class Event; 1162SN/A Event *event; 1171910SN/A GDBListener *listener; 1181910SN/A int number; 1192SN/A 1202SN/A protected: 1213536Sgblack@eecs.umich.edu //The socket commands come in through 1222SN/A int fd; 1232SN/A 1242SN/A protected: 1252SN/A#ifdef notyet 1262SN/A label_t recover; 1272SN/A#endif 1282SN/A bool active; 1292SN/A bool attached; 1302SN/A 1312SN/A System *system; 1322SN/A PhysicalMemory *pmem; 1332680Sktlim@umich.edu ThreadContext *context; 1342SN/A 1352SN/A protected: 1363536Sgblack@eecs.umich.edu class GdbRegCache 1373536Sgblack@eecs.umich.edu { 1383536Sgblack@eecs.umich.edu public: 1393536Sgblack@eecs.umich.edu GdbRegCache(size_t newSize) : regs(new uint64_t[newSize]), size(newSize) 1403536Sgblack@eecs.umich.edu {} 1413536Sgblack@eecs.umich.edu ~GdbRegCache() 1423536Sgblack@eecs.umich.edu { 1433536Sgblack@eecs.umich.edu delete [] regs; 1443536Sgblack@eecs.umich.edu } 1453536Sgblack@eecs.umich.edu 1463536Sgblack@eecs.umich.edu uint64_t * regs; 1473536Sgblack@eecs.umich.edu size_t size; 1483536Sgblack@eecs.umich.edu }; 1493536Sgblack@eecs.umich.edu 1503536Sgblack@eecs.umich.edu GdbRegCache gdbregs; 1513536Sgblack@eecs.umich.edu 1523536Sgblack@eecs.umich.edu protected: 1532SN/A uint8_t getbyte(); 1542SN/A void putbyte(uint8_t b); 1552SN/A 1562SN/A int recv(char *data, int len); 1572SN/A void send(const char *data); 1582SN/A 1592SN/A protected: 1602SN/A // Machine memory 1613536Sgblack@eecs.umich.edu virtual bool read(Addr addr, size_t size, char *data); 1623536Sgblack@eecs.umich.edu virtual bool write(Addr addr, size_t size, const char *data); 1632SN/A 1642SN/A template <class T> T read(Addr addr); 1652SN/A template <class T> void write(Addr addr, T data); 1662SN/A 1672SN/A public: 1683536Sgblack@eecs.umich.edu BaseRemoteGDB(System *system, ThreadContext *context, size_t cacheSize); 1693536Sgblack@eecs.umich.edu virtual ~BaseRemoteGDB(); 1702SN/A 1712680Sktlim@umich.edu void replaceThreadContext(ThreadContext *tc) { context = tc; } 172180SN/A 1732SN/A void attach(int fd); 1742SN/A void detach(); 1752SN/A bool isattached(); 1762SN/A 1773536Sgblack@eecs.umich.edu virtual bool acc(Addr addr, size_t len) = 0; 1782SN/A bool trap(int type); 1792SN/A 1802SN/A protected: 1813536Sgblack@eecs.umich.edu virtual void getregs() = 0; 1823536Sgblack@eecs.umich.edu virtual void setregs() = 0; 1832SN/A 1843536Sgblack@eecs.umich.edu virtual void clearSingleStep() = 0; 1853536Sgblack@eecs.umich.edu virtual void setSingleStep() = 0; 1862SN/A 1872SN/A PCEventQueue *getPcEventQueue(); 1882SN/A 1892SN/A protected: 1902SN/A class HardBreakpoint : public PCEvent 1912SN/A { 1922SN/A private: 1933536Sgblack@eecs.umich.edu BaseRemoteGDB *gdb; 1942SN/A 1952SN/A public: 196507SN/A int refcount; 197507SN/A 198507SN/A public: 1993536Sgblack@eecs.umich.edu HardBreakpoint(BaseRemoteGDB *_gdb, Addr addr); 200507SN/A std::string name() { return gdb->name() + ".hwbkpt"; } 2012SN/A 2022680Sktlim@umich.edu virtual void process(ThreadContext *tc); 2032SN/A }; 2042SN/A friend class HardBreakpoint; 2052SN/A 2062SN/A typedef std::map<Addr, HardBreakpoint *> break_map_t; 2072SN/A typedef break_map_t::iterator break_iter_t; 2082SN/A break_map_t hardBreakMap; 2092SN/A 2102SN/A bool insertSoftBreak(Addr addr, size_t len); 2112SN/A bool removeSoftBreak(Addr addr, size_t len); 2122SN/A bool insertHardBreak(Addr addr, size_t len); 2132SN/A bool removeHardBreak(Addr addr, size_t len); 2142SN/A 2153550Sgblack@eecs.umich.edu protected: 2163550Sgblack@eecs.umich.edu void clearTempBreakpoint(Addr &bkpt); 2173550Sgblack@eecs.umich.edu void setTempBreakpoint(Addr bkpt); 2183550Sgblack@eecs.umich.edu 219507SN/A public: 220507SN/A std::string name(); 2212SN/A}; 2222SN/A 2232SN/Atemplate <class T> 2242SN/Ainline T 2253536Sgblack@eecs.umich.eduBaseRemoteGDB::read(Addr addr) 2262SN/A{ 2272SN/A T temp; 2282SN/A read(addr, sizeof(T), (char *)&temp); 2292SN/A return temp; 2302SN/A} 2312SN/A 2322SN/Atemplate <class T> 2332SN/Ainline void 2343536Sgblack@eecs.umich.eduBaseRemoteGDB::write(Addr addr, T data) 2352SN/A{ write(addr, sizeof(T), (const char *)&data); } 2362SN/A 2372SN/Aclass GDBListener 2382SN/A{ 2392SN/A protected: 2402SN/A class Event : public PollEvent 2412SN/A { 2422SN/A protected: 2432SN/A GDBListener *listener; 2442SN/A 2452SN/A public: 2462SN/A Event(GDBListener *l, int fd, int e); 2472SN/A void process(int revent); 2482SN/A }; 2492SN/A 2502SN/A friend class Event; 2512SN/A Event *event; 2522SN/A 2532SN/A protected: 2542SN/A ListenSocket listener; 2553536Sgblack@eecs.umich.edu BaseRemoteGDB *gdb; 2562SN/A int port; 2572SN/A 2582SN/A public: 2593536Sgblack@eecs.umich.edu GDBListener(BaseRemoteGDB *g, int p); 2602SN/A ~GDBListener(); 2612SN/A 2622SN/A void accept(); 2632SN/A void listen(); 264507SN/A std::string name(); 2652SN/A}; 2662SN/A 2672SN/A#endif /* __REMOTE_GDB_H__ */ 268