diff options
author | Gabe Black <gblack@eecs.umich.edu> | 2006-11-07 05:39:40 -0500 |
---|---|---|
committer | Gabe Black <gblack@eecs.umich.edu> | 2006-11-07 05:39:40 -0500 |
commit | 54e22bfe9591ef6e83613757dd43c4cce2255cef (patch) | |
tree | fe25f255a0cb4887b7cdf1cc40db270e8d66ef6c /src | |
parent | da24915181516740e94efc7de4d9e9263c663e0d (diff) | |
download | gem5-54e22bfe9591ef6e83613757dd43c4cce2255cef.tar.xz |
Broke remote_gdb into a base class and architecture specific derived classes.
--HG--
extra : convert_revision : 8c528fab56a95b8245ad0f2572d62bb556ce0dde
Diffstat (limited to 'src')
-rw-r--r-- | src/arch/alpha/remote_gdb.cc | 137 | ||||
-rw-r--r-- | src/arch/alpha/remote_gdb.hh | 60 | ||||
-rw-r--r-- | src/arch/sparc/remote_gdb.cc | 222 | ||||
-rw-r--r-- | src/arch/sparc/remote_gdb.hh | 80 | ||||
-rw-r--r-- | src/base/remote_gdb.cc | 15 | ||||
-rw-r--r-- | src/base/remote_gdb.hh | 4 |
6 files changed, 73 insertions, 445 deletions
diff --git a/src/arch/alpha/remote_gdb.cc b/src/arch/alpha/remote_gdb.cc index 96c7ea6e2..829e41ca8 100644 --- a/src/arch/alpha/remote_gdb.cc +++ b/src/arch/alpha/remote_gdb.cc @@ -121,8 +121,9 @@ #include <string> #include <unistd.h> -#include "arch/vtophys.hh" +#include "arch/alpha/kgdb.h" #include "arch/alpha/remote_gdb.hh" +#include "arch/vtophys.hh" #include "base/intmath.hh" #include "base/remote_gdb.hh" #include "base/socket.hh" @@ -135,30 +136,12 @@ #include "sim/system.hh" using namespace std; -using namespace AlphaISA; - -RemoteGDB::Event::Event(RemoteGDB *g, int fd, int e) - : PollEvent(fd, e), gdb(g) -{} - -void -RemoteGDB::Event::process(int revent) -{ - if (revent & POLLIN) - gdb->trap(ALPHA_KENTRY_IF); - else if (revent & POLLNVAL) - gdb->detach(); -} +using namespace TheISA; RemoteGDB::RemoteGDB(System *_system, ThreadContext *c) - : BaseRemoteGDB(_system, c, KGDB_NUMREGS), - event(NULL) -{} - -RemoteGDB::~RemoteGDB() + : BaseRemoteGDB(_system, c, KGDB_NUMREGS) { - if (event) - delete event; + memset(gdbregs.regs, 0, gdbregs.size); } /////////////////////////////////////////////////////////// @@ -269,35 +252,15 @@ RemoteGDB::setregs() } void -RemoteGDB::setTempBreakpoint(TempBreakpoint &bkpt, Addr addr) -{ - DPRINTF(GDBMisc, "setTempBreakpoint: addr=%#x\n", addr); - - bkpt.address = addr; - insertHardBreak(addr, 4); -} - -void -RemoteGDB::clearTempBreakpoint(TempBreakpoint &bkpt) -{ - DPRINTF(GDBMisc, "setTempBreakpoint: addr=%#x\n", - bkpt.address); - - - removeHardBreak(bkpt.address, 4); - bkpt.address = 0; -} - -void RemoteGDB::clearSingleStep() { DPRINTF(GDBMisc, "clearSingleStep bt_addr=%#x nt_addr=%#x\n", - takenBkpt.address, notTakenBkpt.address); + takenBkpt, notTakenBkpt); - if (takenBkpt.address != 0) + if (takenBkpt != 0) clearTempBreakpoint(takenBkpt); - if (notTakenBkpt.address != 0) + if (notTakenBkpt != 0) clearTempBreakpoint(notTakenBkpt); } @@ -322,12 +285,12 @@ RemoteGDB::setSingleStep() } DPRINTF(GDBMisc, "setSingleStep bt_addr=%#x nt_addr=%#x\n", - takenBkpt.address, notTakenBkpt.address); + takenBkpt, notTakenBkpt); - setTempBreakpoint(notTakenBkpt, npc); + setTempBreakpoint(notTakenBkpt = npc); if (set_bt) - setTempBreakpoint(takenBkpt, bpc); + setTempBreakpoint(takenBkpt = bpc); } // Write bytes to kernel address space for debugger. @@ -344,81 +307,3 @@ RemoteGDB::write(Addr vaddr, size_t size, const char *data) } } - -PCEventQueue *RemoteGDB::getPcEventQueue() -{ - return &system->pcEventQueue; -} - - -RemoteGDB::HardBreakpoint::HardBreakpoint(RemoteGDB *_gdb, Addr pc) - : PCEvent(_gdb->getPcEventQueue(), "HardBreakpoint Event", pc), - gdb(_gdb), refcount(0) -{ - DPRINTF(GDBMisc, "creating hardware breakpoint at %#x\n", evpc); -} - -void -RemoteGDB::HardBreakpoint::process(ThreadContext *tc) -{ - DPRINTF(GDBMisc, "handling hardware breakpoint at %#x\n", pc()); - - if (tc == gdb->context) - gdb->trap(ALPHA_KENTRY_INT); -} - -bool -RemoteGDB::insertSoftBreak(Addr addr, size_t len) -{ - if (len != sizeof(MachInst)) - panic("invalid length\n"); - - return insertHardBreak(addr, len); -} - -bool -RemoteGDB::removeSoftBreak(Addr addr, size_t len) -{ - if (len != sizeof(MachInst)) - panic("invalid length\n"); - - return removeHardBreak(addr, len); -} - -bool -RemoteGDB::insertHardBreak(Addr addr, size_t len) -{ - if (len != sizeof(MachInst)) - panic("invalid length\n"); - - DPRINTF(GDBMisc, "inserting hardware breakpoint at %#x\n", addr); - - HardBreakpoint *&bkpt = hardBreakMap[addr]; - if (bkpt == 0) - bkpt = new HardBreakpoint(this, addr); - - bkpt->refcount++; - - return true; -} - -bool -RemoteGDB::removeHardBreak(Addr addr, size_t len) -{ - if (len != sizeof(MachInst)) - panic("invalid length\n"); - - DPRINTF(GDBMisc, "removing hardware breakpoint at %#x\n", addr); - - break_iter_t i = hardBreakMap.find(addr); - if (i == hardBreakMap.end()) - return false; - - HardBreakpoint *hbp = (*i).second; - if (--hbp->refcount == 0) { - delete hbp; - hardBreakMap.erase(i); - } - - return true; -} diff --git a/src/arch/alpha/remote_gdb.hh b/src/arch/alpha/remote_gdb.hh index 1dd4ada38..7bef183c3 100644 --- a/src/arch/alpha/remote_gdb.hh +++ b/src/arch/alpha/remote_gdb.hh @@ -48,31 +48,12 @@ namespace AlphaISA { class RemoteGDB : public BaseRemoteGDB { - private: - friend void debugger(); - friend class GDBListener; - - protected: - class Event : public PollEvent - { - protected: - RemoteGDB *gdb; - - public: - Event(RemoteGDB *g, int fd, int e); - void process(int revent); - }; - - friend class Event; - Event *event; - protected: // Machine memory bool write(Addr addr, size_t size, const char *data); public: RemoteGDB(System *system, ThreadContext *context); - ~RemoteGDB(); bool acc(Addr addr, size_t len); @@ -83,47 +64,10 @@ namespace AlphaISA void clearSingleStep(); void setSingleStep(); - PCEventQueue *getPcEventQueue(); - - protected: - class HardBreakpoint : public PCEvent - { - private: - RemoteGDB *gdb; - - public: - int refcount; - - public: - HardBreakpoint(RemoteGDB *_gdb, Addr addr); - std::string name() { return gdb->name() + ".hwbkpt"; } - - virtual void process(ThreadContext *tc); - }; - friend class HardBreakpoint; - - typedef std::map<Addr, HardBreakpoint *> break_map_t; - typedef break_map_t::iterator break_iter_t; - break_map_t hardBreakMap; - - bool insertSoftBreak(Addr addr, size_t len); - bool removeSoftBreak(Addr addr, size_t len); - bool insertHardBreak(Addr addr, size_t len); - bool removeHardBreak(Addr addr, size_t len); - protected: - struct TempBreakpoint { - Addr address; // set here - MachInst bkpt_inst; // saved instruction at bkpt - int init_count; // number of times to skip bkpt - int count; // current count - }; - - TempBreakpoint notTakenBkpt; - TempBreakpoint takenBkpt; - void clearTempBreakpoint(TempBreakpoint &bkpt); - void setTempBreakpoint(TempBreakpoint &bkpt, Addr addr); + Addr notTakenBkpt; + Addr takenBkpt; }; } diff --git a/src/arch/sparc/remote_gdb.cc b/src/arch/sparc/remote_gdb.cc index 2e662af7f..5f9c532b8 100644 --- a/src/arch/sparc/remote_gdb.cc +++ b/src/arch/sparc/remote_gdb.cc @@ -124,7 +124,6 @@ #include "arch/vtophys.hh" #include "arch/sparc/remote_gdb.hh" #include "base/intmath.hh" -#include "base/kgdb.h" #include "base/remote_gdb.hh" #include "base/socket.hh" #include "base/trace.hh" @@ -138,30 +137,10 @@ using namespace std; using namespace TheISA; -RemoteGDB::Event::Event(RemoteGDB *g, int fd, int e) - : PollEvent(fd, e), gdb(g) -{} - -void -RemoteGDB::Event::process(int revent) -{ - if (revent & POLLIN) - gdb->trap(ALPHA_KENTRY_IF); - else if (revent & POLLNVAL) - gdb->detach(); -} - RemoteGDB::RemoteGDB(System *_system, ThreadContext *c) - : BaseRemoteGDB(_system, c, KGDB_NUMREGS), - event(NULL) + : BaseRemoteGDB(_system, c, NumGDBRegs) {} -RemoteGDB::~RemoteGDB() -{ - if (event) - delete event; -} - /////////////////////////////////////////////////////////// // RemoteGDB::acc // @@ -170,6 +149,7 @@ RemoteGDB::~RemoteGDB() bool RemoteGDB::acc(Addr va, size_t len) { +#if 0 Addr last_va; va = TheISA::TruncPage(va); @@ -208,41 +188,11 @@ RemoteGDB::acc(Addr va, size_t len) } while (va < last_va); DPRINTF(GDBAcc, "acc: %#x mapping is valid\n", va); +#endif return true; } /////////////////////////////////////////////////////////// -// RemoteGDB::signal -// -// Translate a trap number into a Unix-compatible signal number. -// (GDB only understands Unix signal numbers.) -// -int -RemoteGDB::signal(int type) -{ - switch (type) { - case ALPHA_KENTRY_INT: - return (SIGTRAP); - - case ALPHA_KENTRY_UNA: - return (SIGBUS); - - case ALPHA_KENTRY_ARITH: - return (SIGFPE); - - case ALPHA_KENTRY_IF: - return (SIGILL); - - case ALPHA_KENTRY_MM: - return (SIGSEGV); - - default: - panic("unknown signal type"); - return 0; - } -} - -/////////////////////////////////////////////////////////// // RemoteGDB::getregs // // Translate the kernel debugger register format into @@ -252,24 +202,14 @@ RemoteGDB::getregs() { memset(gdbregs.regs, 0, gdbregs.size); - gdbregs.regs[KGDB_REG_PC] = context->readPC(); - - // @todo: Currently this is very Alpha specific. - if (AlphaISA::PcPAL(gdbregs.regs[KGDB_REG_PC])) { - for (int i = 0; i < TheISA::NumIntArchRegs; ++i) { - gdbregs.regs[i] = context->readIntReg(AlphaISA::reg_redir[i]); - } - } else { - for (int i = 0; i < TheISA::NumIntArchRegs; ++i) { - gdbregs.regs[i] = context->readIntReg(i); - } - } - -#ifdef KGDB_FP_REGS - for (int i = 0; i < TheISA::NumFloatArchRegs; ++i) { - gdbregs.regs[i + KGDB_REG_F0] = context->readFloatRegBits(i); - } -#endif + gdbregs.regs[RegPc] = context->readPC(); + gdbregs.regs[RegNpc] = context->readNextPC(); + for(int x = RegG0; x <= RegI7; x++) + gdbregs.regs[x] = context->readIntReg(x - RegG0); + for(int x = RegF0; x <= RegF31; x++) + gdbregs.regs[x] = context->readFloatRegBits(x - RegF0); + gdbregs.regs[RegY] = context->readMiscReg(MISCREG_Y); + //XXX need to also load up Psr, Wim, Tbr, Fpsr, and Cpsr } /////////////////////////////////////////////////////////// @@ -281,48 +221,20 @@ RemoteGDB::getregs() void RemoteGDB::setregs() { - // @todo: Currently this is very Alpha specific. - if (AlphaISA::PcPAL(gdbregs.regs[KGDB_REG_PC])) { - for (int i = 0; i < TheISA::NumIntArchRegs; ++i) { - context->setIntReg(AlphaISA::reg_redir[i], gdbregs.regs[i]); - } - } else { - for (int i = 0; i < TheISA::NumIntArchRegs; ++i) { - context->setIntReg(i, gdbregs.regs[i]); - } - } - -#ifdef KGDB_FP_REGS - for (int i = 0; i < TheISA::NumFloatArchRegs; ++i) { - context->setFloatRegBits(i, gdbregs.regs[i + KGDB_REG_F0]); - } -#endif - context->setPC(gdbregs.regs[KGDB_REG_PC]); -} - -void -RemoteGDB::setTempBreakpoint(TempBreakpoint &bkpt, Addr addr) -{ - DPRINTF(GDBMisc, "setTempBreakpoint: addr=%#x\n", addr); - - bkpt.address = addr; - insertHardBreak(addr, 4); -} - -void -RemoteGDB::clearTempBreakpoint(TempBreakpoint &bkpt) -{ - DPRINTF(GDBMisc, "setTempBreakpoint: addr=%#x\n", - bkpt.address); - - - removeHardBreak(bkpt.address, 4); - bkpt.address = 0; + context->setPC(gdbregs.regs[RegPc]); + context->setNextPC(gdbregs.regs[RegNpc]); + for(int x = RegG0; x <= RegI7; x++) + context->setIntReg(x - RegG0, gdbregs.regs[x]); + for(int x = RegF0; x <= RegF31; x++) + context->setFloatRegBits(x - RegF0, gdbregs.regs[x]); + context->setMiscRegWithEffect(MISCREG_Y, gdbregs.regs[RegY]); + //XXX need to also set Psr, Wim, Tbr, Fpsr, and Cpsr } void RemoteGDB::clearSingleStep() { +#if 0 DPRINTF(GDBMisc, "clearSingleStep bt_addr=%#x nt_addr=%#x\n", takenBkpt.address, notTakenBkpt.address); @@ -331,11 +243,13 @@ RemoteGDB::clearSingleStep() if (notTakenBkpt.address != 0) clearTempBreakpoint(notTakenBkpt); +#endif } void RemoteGDB::setSingleStep() { +#if 0 Addr pc = context->readPC(); Addr npc, bpc; bool set_bt = false; @@ -360,97 +274,5 @@ RemoteGDB::setSingleStep() if (set_bt) setTempBreakpoint(takenBkpt, bpc); -} - -// Write bytes to kernel address space for debugger. -bool -RemoteGDB::write(Addr vaddr, size_t size, const char *data) -{ - if (BaseRemoteGDB::write(vaddr, size, data)) { -#ifdef IMB - alpha_pal_imb(); #endif - return true; - } else { - return false; - } -} - - -PCEventQueue *RemoteGDB::getPcEventQueue() -{ - return &system->pcEventQueue; -} - - -RemoteGDB::HardBreakpoint::HardBreakpoint(RemoteGDB *_gdb, Addr pc) - : PCEvent(_gdb->getPcEventQueue(), "HardBreakpoint Event", pc), - gdb(_gdb), refcount(0) -{ - DPRINTF(GDBMisc, "creating hardware breakpoint at %#x\n", evpc); -} - -void -RemoteGDB::HardBreakpoint::process(ThreadContext *tc) -{ - DPRINTF(GDBMisc, "handling hardware breakpoint at %#x\n", pc()); - - if (tc == gdb->context) - gdb->trap(ALPHA_KENTRY_INT); -} - -bool -RemoteGDB::insertSoftBreak(Addr addr, size_t len) -{ - if (len != sizeof(MachInst)) - panic("invalid length\n"); - - return insertHardBreak(addr, len); -} - -bool -RemoteGDB::removeSoftBreak(Addr addr, size_t len) -{ - if (len != sizeof(MachInst)) - panic("invalid length\n"); - - return removeHardBreak(addr, len); -} - -bool -RemoteGDB::insertHardBreak(Addr addr, size_t len) -{ - if (len != sizeof(MachInst)) - panic("invalid length\n"); - - DPRINTF(GDBMisc, "inserting hardware breakpoint at %#x\n", addr); - - HardBreakpoint *&bkpt = hardBreakMap[addr]; - if (bkpt == 0) - bkpt = new HardBreakpoint(this, addr); - - bkpt->refcount++; - - return true; -} - -bool -RemoteGDB::removeHardBreak(Addr addr, size_t len) -{ - if (len != sizeof(MachInst)) - panic("invalid length\n"); - - DPRINTF(GDBMisc, "removing hardware breakpoint at %#x\n", addr); - - break_iter_t i = hardBreakMap.find(addr); - if (i == hardBreakMap.end()) - return false; - - HardBreakpoint *hbp = (*i).second; - if (--hbp->refcount == 0) { - delete hbp; - hardBreakMap.erase(i); - } - - return true; } diff --git a/src/arch/sparc/remote_gdb.hh b/src/arch/sparc/remote_gdb.hh index 6ac4f296f..3ded1e218 100644 --- a/src/arch/sparc/remote_gdb.hh +++ b/src/arch/sparc/remote_gdb.hh @@ -46,34 +46,32 @@ namespace SparcISA { class RemoteGDB : public BaseRemoteGDB { - private: - friend void debugger(); - friend class GDBListener; - protected: - class Event : public PollEvent + enum RegisterConstants { - protected: - RemoteGDB *gdb; - - public: - Event(RemoteGDB *g, int fd, int e); - void process(int revent); + RegG0, RegG1, RegG2, RegG3, RegG4, RegG5, RegG6, RegG7, + RegO0, RegO1, RegO2, RegO3, RegO4, RegO5, RegO6, RegO7, + RegL0, RegL1, RegL2, RegL3, RegL4, RegL5, RegL6, RegL7, + RegI0, RegI1, RegI2, RegI3, RegI4, RegI5, RegI6, RegI7, + RegF0, RegF1, RegF2, RegF3, RegF4, RegF5, RegF6, RegF7, + RegF8, RegF9, RegF10, RegF11, RegF12, RegF13, RegF14, RegF15, + RegF16, RegF17, RegF18, RegF19, RegF20, RegF21, RegF22, RegF23, + RegF24, RegF25, RegF26, RegF27, RegF28, RegF29, RegF30, RegF31, + RegY, + RegPsr, + RegWim, + RegTbr, + RegPc, + RegNpc, + RegFpsr, + RegCpsr, + NumGDBRegs }; - friend class Event; - Event *event; - - protected: - // Machine memory - bool write(Addr addr, size_t size, const char *data); - public: RemoteGDB(System *system, ThreadContext *context); - ~RemoteGDB(); bool acc(Addr addr, size_t len); - int signal(int type); protected: void getregs(); @@ -82,47 +80,7 @@ namespace SparcISA void clearSingleStep(); void setSingleStep(); - PCEventQueue *getPcEventQueue(); - - protected: - class HardBreakpoint : public PCEvent - { - private: - RemoteGDB *gdb; - - public: - int refcount; - - public: - HardBreakpoint(RemoteGDB *_gdb, Addr addr); - std::string name() { return gdb->name() + ".hwbkpt"; } - - virtual void process(ThreadContext *tc); - }; - friend class HardBreakpoint; - - typedef std::map<Addr, HardBreakpoint *> break_map_t; - typedef break_map_t::iterator break_iter_t; - break_map_t hardBreakMap; - - bool insertSoftBreak(Addr addr, size_t len); - bool removeSoftBreak(Addr addr, size_t len); - bool insertHardBreak(Addr addr, size_t len); - bool removeHardBreak(Addr addr, size_t len); - - protected: - struct TempBreakpoint { - Addr address; // set here - MachInst bkpt_inst; // saved instruction at bkpt - int init_count; // number of times to skip bkpt - int count; // current count - }; - - TempBreakpoint notTakenBkpt; - TempBreakpoint takenBkpt; - - void clearTempBreakpoint(TempBreakpoint &bkpt); - void setTempBreakpoint(TempBreakpoint &bkpt, Addr addr); + Addr singleStepBreaks[2]; }; } diff --git a/src/base/remote_gdb.cc b/src/base/remote_gdb.cc index 01166d46f..fae814904 100644 --- a/src/base/remote_gdb.cc +++ b/src/base/remote_gdb.cc @@ -571,6 +571,21 @@ BaseRemoteGDB::removeHardBreak(Addr addr, size_t len) return true; } +void +BaseRemoteGDB::setTempBreakpoint(Addr bkpt) +{ + DPRINTF(GDBMisc, "setTempBreakpoint: addr=%#x\n", bkpt); + insertHardBreak(bkpt, sizeof(TheISA::MachInst)); +} + +void +BaseRemoteGDB::clearTempBreakpoint(Addr &bkpt) +{ + DPRINTF(GDBMisc, "setTempBreakpoint: addr=%#x\n", bkpt); + removeHardBreak(bkpt, sizeof(TheISA::MachInst)); + bkpt = 0; +} + const char * BaseRemoteGDB::break_type(char c) { diff --git a/src/base/remote_gdb.hh b/src/base/remote_gdb.hh index 65e4313eb..4a1754afd 100644 --- a/src/base/remote_gdb.hh +++ b/src/base/remote_gdb.hh @@ -212,6 +212,10 @@ class BaseRemoteGDB bool insertHardBreak(Addr addr, size_t len); bool removeHardBreak(Addr addr, size_t len); + protected: + void clearTempBreakpoint(Addr &bkpt); + void setTempBreakpoint(Addr bkpt); + public: std::string name(); }; |