changeset 6efb37480d87 in /z/repo/gem5
details: http://repo.gem5.org/gem5?cmd=changeset;node=6efb37480d87
description:
        misc: Generalize GDB single stepping.

        The new single stepping implementation for x86 doesn't rely on any ISA
        specific properties or functionality. This change pulls out the per ISA
        implementation of those functions and promotes the X86 implementation 
to the
        base class.

        One drawback of that implementation is that the CPU might stop on an
        instruction twice if it's affected by both breakpoints and single 
stepping.
        While that might be a little surprising, it's harmless and would only 
happen
        under somewhat unlikely circumstances.

diffstat:

 src/arch/alpha/remote_gdb.cc |  40 ----------------------------------------
 src/arch/alpha/remote_gdb.hh |   9 +--------
 src/arch/arm/remote_gdb.cc   |  43 +------------------------------------------
 src/arch/arm/remote_gdb.hh   |  22 +++++++---------------
 src/arch/mips/remote_gdb.cc  |  44 --------------------------------------------
 src/arch/mips/remote_gdb.hh  |   7 -------
 src/arch/power/remote_gdb.hh |  12 ------------
 src/arch/sparc/remote_gdb.cc |  16 +---------------
 src/arch/sparc/remote_gdb.hh |   5 -----
 src/arch/x86/remote_gdb.cc   |  23 +----------------------
 src/arch/x86/remote_gdb.hh   |  17 -----------------
 src/base/remote_gdb.cc       |  30 +++++++++++++++++++++++++-----
 src/base/remote_gdb.hh       |  18 ++++++++++++++++--
 13 files changed, 52 insertions(+), 234 deletions(-)

diffs (truncated from 464 to 300 lines):

diff -r e60c7758cf69 -r 6efb37480d87 src/arch/alpha/remote_gdb.cc
--- a/src/arch/alpha/remote_gdb.cc      Fri Dec 05 22:36:16 2014 -0800
+++ b/src/arch/alpha/remote_gdb.cc      Fri Dec 05 22:37:03 2014 -0800
@@ -255,46 +255,6 @@
     context->pcState(gdbregs.regs64[KGDB_REG_PC]);
 }
 
-void
-RemoteGDB::clearSingleStep()
-{
-    DPRINTF(GDBMisc, "clearSingleStep bt_addr=%#x nt_addr=%#x\n",
-            takenBkpt, notTakenBkpt);
-
-    if (takenBkpt != 0)
-        clearTempBreakpoint(takenBkpt);
-
-    if (notTakenBkpt != 0)
-        clearTempBreakpoint(notTakenBkpt);
-}
-
-void
-RemoteGDB::setSingleStep()
-{
-    PCState pc = context->pcState();
-    PCState bpc;
-    bool set_bt = false;
-
-    // User was stopped at pc, e.g. the instruction at pc was not
-    // executed.
-    MachInst inst = read<MachInst>(pc.pc());
-    StaticInstPtr si = context->getDecoderPtr()->decode(inst, pc.pc());
-    if (si->hasBranchTarget(pc, context, bpc)) {
-        // Don't bother setting a breakpoint on the taken branch if it
-        // is the same as the next pc
-        if (bpc.pc() != pc.npc())
-            set_bt = true;
-    }
-
-    DPRINTF(GDBMisc, "setSingleStep bt_addr=%#x nt_addr=%#x\n",
-            takenBkpt, notTakenBkpt);
-
-    setTempBreakpoint(notTakenBkpt = pc.npc());
-
-    if (set_bt)
-        setTempBreakpoint(takenBkpt = bpc.pc());
-}
-
 // Write bytes to kernel address space for debugger.
 bool
 RemoteGDB::write(Addr vaddr, size_t size, const char *data)
diff -r e60c7758cf69 -r 6efb37480d87 src/arch/alpha/remote_gdb.hh
--- a/src/arch/alpha/remote_gdb.hh      Fri Dec 05 22:36:16 2014 -0800
+++ b/src/arch/alpha/remote_gdb.hh      Fri Dec 05 22:37:03 2014 -0800
@@ -48,21 +48,14 @@
 class RemoteGDB : public BaseRemoteGDB
 {
   protected:
-    Addr notTakenBkpt;
-    Addr takenBkpt;
-
-  protected:
     void getregs();
     void setregs();
 
-    void clearSingleStep();
-    void setSingleStep();
-
     // Machine memory
     bool acc(Addr addr, size_t len);
     bool write(Addr addr, size_t size, const char *data);
 
-    virtual bool insertHardBreak(Addr addr, size_t len);
+    bool insertHardBreak(Addr addr, size_t len);
 
   public:
     RemoteGDB(System *system, ThreadContext *context);
diff -r e60c7758cf69 -r 6efb37480d87 src/arch/arm/remote_gdb.cc
--- a/src/arch/arm/remote_gdb.cc        Fri Dec 05 22:36:16 2014 -0800
+++ b/src/arch/arm/remote_gdb.cc        Fri Dec 05 22:37:03 2014 -0800
@@ -161,8 +161,7 @@
 using namespace ArmISA;
 
 RemoteGDB::RemoteGDB(System *_system, ThreadContext *tc)
-    : BaseRemoteGDB(_system, tc, GDB_REG_BYTES),
-      notTakenBkpt(0), takenBkpt(0)
+    : BaseRemoteGDB(_system, tc, GDB_REG_BYTES)
 {
 }
 
@@ -314,46 +313,6 @@
     }
 }
 
-void
-RemoteGDB::clearSingleStep()
-{
-    DPRINTF(GDBMisc, "clearSingleStep bt_addr=%#x nt_addr=%#x\n",
-            takenBkpt, notTakenBkpt);
-
-    if (takenBkpt != 0)
-        clearTempBreakpoint(takenBkpt);
-
-    if (notTakenBkpt != 0)
-        clearTempBreakpoint(notTakenBkpt);
-}
-
-void
-RemoteGDB::setSingleStep()
-{
-    PCState pc = context->pcState();
-    PCState bpc;
-    bool set_bt = false;
-
-    // User was stopped at pc, e.g. the instruction at pc was not
-    // executed.
-    MachInst inst = read<MachInst>(pc.pc());
-    StaticInstPtr si = context->getDecoderPtr()->decode(inst, pc.pc());
-    if (si->hasBranchTarget(pc, context, bpc)) {
-        // Don't bother setting a breakpoint on the taken branch if it
-        // is the same as the next pc
-        if (bpc.pc() != pc.npc())
-            set_bt = true;
-    }
-
-    DPRINTF(GDBMisc, "setSingleStep bt_addr=%#x nt_addr=%#x\n",
-            takenBkpt, notTakenBkpt);
-
-    setTempBreakpoint(notTakenBkpt = pc.npc());
-
-    if (set_bt)
-        setTempBreakpoint(takenBkpt = bpc.pc());
-}
-
 // Write bytes to kernel address space for debugger.
 bool
 RemoteGDB::write(Addr vaddr, size_t size, const char *data)
diff -r e60c7758cf69 -r 6efb37480d87 src/arch/arm/remote_gdb.hh
--- a/src/arch/arm/remote_gdb.hh        Fri Dec 05 22:36:16 2014 -0800
+++ b/src/arch/arm/remote_gdb.hh        Fri Dec 05 22:37:03 2014 -0800
@@ -80,23 +80,15 @@
 
 class RemoteGDB : public BaseRemoteGDB
 {
+  protected:
+    bool acc(Addr addr, size_t len);
+    bool write(Addr addr, size_t size, const char *data);
 
-protected:
-  Addr notTakenBkpt;
-  Addr takenBkpt;
+    void getregs();
+    void setregs();
 
-protected:
-  bool acc(Addr addr, size_t len);
-  bool write(Addr addr, size_t size, const char *data);
-
-  void getregs();
-  void setregs();
-
-  void clearSingleStep();
-  void setSingleStep();
-
-public:
-  RemoteGDB(System *_system, ThreadContext *tc);
+  public:
+    RemoteGDB(System *_system, ThreadContext *tc);
 };
 } // namespace ArmISA
 
diff -r e60c7758cf69 -r 6efb37480d87 src/arch/mips/remote_gdb.cc
--- a/src/arch/mips/remote_gdb.cc       Fri Dec 05 22:36:16 2014 -0800
+++ b/src/arch/mips/remote_gdb.cc       Fri Dec 05 22:37:03 2014 -0800
@@ -235,47 +235,3 @@
     context->setFloatRegBits(FLOATREG_FIR,
         gdbregs.regs32[GdbIntRegs + GdbFloatArchRegs + 1]);
 }
-
-void
-RemoteGDB::clearSingleStep()
-{
-    DPRINTF(GDBMisc, "clearSingleStep bt_addr=%#x nt_addr=%#x\n",
-            takenBkpt, notTakenBkpt);
-
-    if (takenBkpt != 0)
-        clearTempBreakpoint(takenBkpt);
-
-    if (notTakenBkpt != 0)
-        clearTempBreakpoint(notTakenBkpt);
-}
-
-void
-RemoteGDB::setSingleStep()
-{
-    PCState pc = context->pcState();
-    PCState bpc;
-    bool set_bt = false;
-
-    // User was stopped at pc, e.g. the instruction at pc was not
-    // executed.
-    MachInst inst = read<MachInst>(pc.pc());
-    StaticInstPtr si = context->getDecoderPtr()->decode(inst, pc.pc());
-    if (si->hasBranchTarget(pc, context, bpc)) {
-        // Don't bother setting a breakpoint on the taken branch if it
-        // is the same as the next npc
-        if (bpc.npc() != pc.nnpc())
-            set_bt = true;
-    }
-
-    DPRINTF(GDBMisc, "setSingleStep bt_addr=%#x nt_addr=%#x\n",
-            takenBkpt, notTakenBkpt);
-
-    notTakenBkpt = pc.nnpc();
-    setTempBreakpoint(notTakenBkpt);
-
-    if (set_bt) {
-        takenBkpt = bpc.npc();
-        setTempBreakpoint(takenBkpt);
-    }
-}
-
diff -r e60c7758cf69 -r 6efb37480d87 src/arch/mips/remote_gdb.hh
--- a/src/arch/mips/remote_gdb.hh       Fri Dec 05 22:36:16 2014 -0800
+++ b/src/arch/mips/remote_gdb.hh       Fri Dec 05 22:37:03 2014 -0800
@@ -54,10 +54,6 @@
 
     class RemoteGDB : public BaseRemoteGDB
     {
-      protected:
-        Addr notTakenBkpt;
-        Addr takenBkpt;
-
       public:
         RemoteGDB(System *_system, ThreadContext *tc);
 
@@ -66,9 +62,6 @@
 
         void getregs();
         void setregs();
-
-        void clearSingleStep();
-        void setSingleStep();
     };
 }
 
diff -r e60c7758cf69 -r 6efb37480d87 src/arch/power/remote_gdb.hh
--- a/src/arch/power/remote_gdb.hh      Fri Dec 05 22:36:16 2014 -0800
+++ b/src/arch/power/remote_gdb.hh      Fri Dec 05 22:37:03 2014 -0800
@@ -65,18 +65,6 @@
     {
         panic("setregs not implemented for POWER!");
     }
-
-    void
-    clearSingleStep()
-    {
-        panic("clearSingleStep not implemented for POWER!");
-    }
-
-    void
-    setSingleStep()
-    {
-        panic("setSingleStep not implemented for POWER!");
-    }
 };
 
 } // namespace PowerISA
diff -r e60c7758cf69 -r 6efb37480d87 src/arch/sparc/remote_gdb.cc
--- a/src/arch/sparc/remote_gdb.cc      Fri Dec 05 22:36:16 2014 -0800
+++ b/src/arch/sparc/remote_gdb.cc      Fri Dec 05 22:37:03 2014 -0800
@@ -144,7 +144,7 @@
 using namespace SparcISA;
 
 RemoteGDB::RemoteGDB(System *_system, ThreadContext *c)
-    : BaseRemoteGDB(_system, c, NumGDBRegs * sizeof(uint64_t)), nextBkpt(0)
+    : BaseRemoteGDB(_system, c, NumGDBRegs * sizeof(uint64_t))
 {}
 
 ///////////////////////////////////////////////////////////
@@ -241,17 +241,3 @@
         context->setIntReg(x - RegG0, gdbregs.regs64[x]);
     // Only the integer registers, pc and npc are set in netbsd
 }
-
-void
-RemoteGDB::clearSingleStep()
-{
-   if (nextBkpt)
-       clearTempBreakpoint(nextBkpt);
-}
-
-void
-RemoteGDB::setSingleStep()
-{
-    nextBkpt = context->pcState().npc();
-    setTempBreakpoint(nextBkpt);
-}
diff -r e60c7758cf69 -r 6efb37480d87 src/arch/sparc/remote_gdb.hh
--- a/src/arch/sparc/remote_gdb.hh      Fri Dec 05 22:36:16 2014 -0800
+++ b/src/arch/sparc/remote_gdb.hh      Fri Dec 05 22:37:03 2014 -0800
_______________________________________________
gem5-dev mailing list
gem5-dev@gem5.org
http://m5sim.org/mailman/listinfo/gem5-dev

Reply via email to