summaryrefslogtreecommitdiff
path: root/src/arch
diff options
context:
space:
mode:
Diffstat (limited to 'src/arch')
-rw-r--r--src/arch/x86/remote_gdb.cc188
-rw-r--r--src/arch/x86/remote_gdb.hh102
2 files changed, 263 insertions, 27 deletions
diff --git a/src/arch/x86/remote_gdb.cc b/src/arch/x86/remote_gdb.cc
index c7bce59bf..b30bf5739 100644
--- a/src/arch/x86/remote_gdb.cc
+++ b/src/arch/x86/remote_gdb.cc
@@ -1,4 +1,5 @@
/*
+ * Copyright 2014 Google, Inc.
* Copyright (c) 2007 The Hewlett-Packard Development Company
* All rights reserved.
*
@@ -42,41 +43,204 @@
#include <string>
+#include "arch/x86/regs/int.hh"
+#include "arch/x86/regs/misc.hh"
+#include "arch/x86/pagetable_walker.hh"
+#include "arch/x86/process.hh"
#include "arch/x86/remote_gdb.hh"
#include "arch/vtophys.hh"
#include "base/remote_gdb.hh"
#include "base/socket.hh"
#include "base/trace.hh"
+#include "cpu/base.hh"
#include "cpu/thread_context.hh"
+#include "mem/page_table.hh"
+#include "sim/full_system.hh"
using namespace std;
using namespace X86ISA;
-RemoteGDB::RemoteGDB(System *_system, ThreadContext *c)
- : BaseRemoteGDB(_system, c, NumGDBRegs)
+RemoteGDB::RemoteGDB(System *_system, ThreadContext *c) :
+ BaseRemoteGDB(_system, c, GDB_REG_BYTES), singleStepEvent(this)
{}
-bool RemoteGDB::acc(Addr va, size_t len)
+bool
+RemoteGDB::acc(Addr va, size_t len)
{
- panic("Remote gdb acc not implemented in x86!\n");
+ if (FullSystem) {
+ Walker *walker = context->getDTBPtr()->getWalker();
+ unsigned logBytes;
+ Fault fault = walker->startFunctional(context, va, logBytes,
+ BaseTLB::Read);
+ if (fault != NoFault)
+ return false;
+
+ Addr endVa = va + len - 1;
+ if ((va & ~mask(logBytes)) == (endVa & ~mask(logBytes)))
+ return true;
+
+ fault = walker->startFunctional(context, endVa, logBytes,
+ BaseTLB::Read);
+ return fault == NoFault;
+ } else {
+ TlbEntry entry;
+ return context->getProcessPtr()->pTable->lookup(va, entry);
+ }
+}
+
+void
+RemoteGDB::SingleStepEvent::process()
+{
+ if (!gdb->singleStepEvent.scheduled())
+ gdb->scheduleInstCommitEvent(&gdb->singleStepEvent, 1);
+ gdb->trap(SIGTRAP);
}
-void RemoteGDB::getregs()
+void
+RemoteGDB::getregs()
{
- panic("Remote gdb getregs not implemented in x86!\n");
+ HandyM5Reg m5reg = context->readMiscRegNoEffect(MISCREG_M5_REG);
+ if (m5reg.submode == SixtyFourBitMode) {
+ gdbregs.regs64[GDB64_RAX] = context->readIntReg(INTREG_RAX);
+ gdbregs.regs64[GDB64_RBX] = context->readIntReg(INTREG_RBX);
+ gdbregs.regs64[GDB64_RCX] = context->readIntReg(INTREG_RCX);
+ gdbregs.regs64[GDB64_RDX] = context->readIntReg(INTREG_RDX);
+ gdbregs.regs64[GDB64_RSI] = context->readIntReg(INTREG_RSI);
+ gdbregs.regs64[GDB64_RDI] = context->readIntReg(INTREG_RDI);
+ gdbregs.regs64[GDB64_RBP] = context->readIntReg(INTREG_RBP);
+ gdbregs.regs64[GDB64_RSP] = context->readIntReg(INTREG_RSP);
+ gdbregs.regs64[GDB64_R8] = context->readIntReg(INTREG_R8);
+ gdbregs.regs64[GDB64_R9] = context->readIntReg(INTREG_R9);
+ gdbregs.regs64[GDB64_R10] = context->readIntReg(INTREG_R10);
+ gdbregs.regs64[GDB64_R11] = context->readIntReg(INTREG_R11);
+ gdbregs.regs64[GDB64_R12] = context->readIntReg(INTREG_R12);
+ gdbregs.regs64[GDB64_R13] = context->readIntReg(INTREG_R13);
+ gdbregs.regs64[GDB64_R14] = context->readIntReg(INTREG_R14);
+ gdbregs.regs64[GDB64_R15] = context->readIntReg(INTREG_R15);
+ gdbregs.regs64[GDB64_RIP] = context->pcState().pc();
+ gdbregs.regs32[GDB64_RFLAGS_32] =
+ context->readMiscRegNoEffect(MISCREG_RFLAGS);
+ gdbregs.regs32[GDB64_CS_32] = context->readMiscRegNoEffect(MISCREG_CS);
+ gdbregs.regs32[GDB64_SS_32] = context->readMiscRegNoEffect(MISCREG_SS);
+ gdbregs.regs32[GDB64_DS_32] = context->readMiscRegNoEffect(MISCREG_DS);
+ gdbregs.regs32[GDB64_ES_32] = context->readMiscRegNoEffect(MISCREG_ES);
+ gdbregs.regs32[GDB64_FS_32] = context->readMiscRegNoEffect(MISCREG_FS);
+ gdbregs.regs32[GDB64_GS_32] = context->readMiscRegNoEffect(MISCREG_GS);
+ } else {
+ gdbregs.regs32[GDB32_EAX] = context->readIntReg(INTREG_RAX);
+ gdbregs.regs32[GDB32_ECX] = context->readIntReg(INTREG_RCX);
+ gdbregs.regs32[GDB32_EDX] = context->readIntReg(INTREG_RDX);
+ gdbregs.regs32[GDB32_EBX] = context->readIntReg(INTREG_RBX);
+ gdbregs.regs32[GDB32_ESP] = context->readIntReg(INTREG_RSP);
+ gdbregs.regs32[GDB32_EBP] = context->readIntReg(INTREG_RBP);
+ gdbregs.regs32[GDB32_ESI] = context->readIntReg(INTREG_RSI);
+ gdbregs.regs32[GDB32_EDI] = context->readIntReg(INTREG_RDI);
+ gdbregs.regs32[GDB32_EIP] = context->pcState().pc();
+ gdbregs.regs32[GDB32_EFLAGS] =
+ context->readMiscRegNoEffect(MISCREG_RFLAGS);
+ gdbregs.regs32[GDB32_CS] = context->readMiscRegNoEffect(MISCREG_CS);
+ gdbregs.regs32[GDB32_CS] = context->readMiscRegNoEffect(MISCREG_SS);
+ gdbregs.regs32[GDB32_CS] = context->readMiscRegNoEffect(MISCREG_DS);
+ gdbregs.regs32[GDB32_CS] = context->readMiscRegNoEffect(MISCREG_ES);
+ gdbregs.regs32[GDB32_CS] = context->readMiscRegNoEffect(MISCREG_FS);
+ gdbregs.regs32[GDB32_CS] = context->readMiscRegNoEffect(MISCREG_GS);
+ }
}
-void RemoteGDB::setregs()
+void
+RemoteGDB::setregs()
{
- panic("Remote gdb setregs not implemented in x86!\n");
+ HandyM5Reg m5reg = context->readMiscRegNoEffect(MISCREG_M5_REG);
+ if (m5reg.submode == SixtyFourBitMode) {
+ context->setIntReg(INTREG_RAX, gdbregs.regs64[GDB64_RAX]);
+ context->setIntReg(INTREG_RBX, gdbregs.regs64[GDB64_RBX]);
+ context->setIntReg(INTREG_RCX, gdbregs.regs64[GDB64_RCX]);
+ context->setIntReg(INTREG_RDX, gdbregs.regs64[GDB64_RDX]);
+ context->setIntReg(INTREG_RSI, gdbregs.regs64[GDB64_RSI]);
+ context->setIntReg(INTREG_RDI, gdbregs.regs64[GDB64_RDI]);
+ context->setIntReg(INTREG_RBP, gdbregs.regs64[GDB64_RBP]);
+ context->setIntReg(INTREG_RSP, gdbregs.regs64[GDB64_RSP]);
+ context->setIntReg(INTREG_R8, gdbregs.regs64[GDB64_R8]);
+ context->setIntReg(INTREG_R9, gdbregs.regs64[GDB64_R9]);
+ context->setIntReg(INTREG_R10, gdbregs.regs64[GDB64_R10]);
+ context->setIntReg(INTREG_R11, gdbregs.regs64[GDB64_R11]);
+ context->setIntReg(INTREG_R12, gdbregs.regs64[GDB64_R12]);
+ context->setIntReg(INTREG_R13, gdbregs.regs64[GDB64_R13]);
+ context->setIntReg(INTREG_R14, gdbregs.regs64[GDB64_R14]);
+ context->setIntReg(INTREG_R15, gdbregs.regs64[GDB64_R15]);
+ context->pcState(gdbregs.regs64[GDB64_RIP]);
+ context->setMiscReg(MISCREG_RFLAGS, gdbregs.regs32[GDB64_RFLAGS_32]);
+ if (gdbregs.regs32[GDB64_CS_32] !=
+ context->readMiscRegNoEffect(MISCREG_CS)) {
+ warn("Remote gdb: Ignoring update to CS.\n");
+ }
+ if (gdbregs.regs32[GDB64_SS_32] !=
+ context->readMiscRegNoEffect(MISCREG_SS)) {
+ warn("Remote gdb: Ignoring update to SS.\n");
+ }
+ if (gdbregs.regs32[GDB64_DS_32] !=
+ context->readMiscRegNoEffect(MISCREG_DS)) {
+ warn("Remote gdb: Ignoring update to DS.\n");
+ }
+ if (gdbregs.regs32[GDB64_ES_32] !=
+ context->readMiscRegNoEffect(MISCREG_ES)) {
+ warn("Remote gdb: Ignoring update to ES.\n");
+ }
+ if (gdbregs.regs32[GDB64_FS_32] !=
+ context->readMiscRegNoEffect(MISCREG_FS)) {
+ warn("Remote gdb: Ignoring update to FS.\n");
+ }
+ if (gdbregs.regs32[GDB64_GS_32] !=
+ context->readMiscRegNoEffect(MISCREG_GS)) {
+ warn("Remote gdb: Ignoring update to GS.\n");
+ }
+ } else {
+ context->setIntReg(INTREG_RAX, gdbregs.regs32[GDB32_EAX]);
+ context->setIntReg(INTREG_RCX, gdbregs.regs32[GDB32_ECX]);
+ context->setIntReg(INTREG_RDX, gdbregs.regs32[GDB32_EDX]);
+ context->setIntReg(INTREG_RBX, gdbregs.regs32[GDB32_EBX]);
+ context->setIntReg(INTREG_RSP, gdbregs.regs32[GDB32_ESP]);
+ context->setIntReg(INTREG_RBP, gdbregs.regs32[GDB32_EBP]);
+ context->setIntReg(INTREG_RSI, gdbregs.regs32[GDB32_ESI]);
+ context->setIntReg(INTREG_RDI, gdbregs.regs32[GDB32_EDI]);
+ context->pcState(gdbregs.regs32[GDB32_EIP]);
+ context->setMiscReg(MISCREG_RFLAGS, gdbregs.regs32[GDB32_EFLAGS]);
+ if (gdbregs.regs32[GDB64_CS_32] !=
+ context->readMiscRegNoEffect(MISCREG_CS)) {
+ warn("Remote gdb: Ignoring update to CS.\n");
+ }
+ if (gdbregs.regs32[GDB32_SS] !=
+ context->readMiscRegNoEffect(MISCREG_SS)) {
+ warn("Remote gdb: Ignoring update to SS.\n");
+ }
+ if (gdbregs.regs32[GDB32_DS] !=
+ context->readMiscRegNoEffect(MISCREG_DS)) {
+ warn("Remote gdb: Ignoring update to DS.\n");
+ }
+ if (gdbregs.regs32[GDB32_ES] !=
+ context->readMiscRegNoEffect(MISCREG_ES)) {
+ warn("Remote gdb: Ignoring update to ES.\n");
+ }
+ if (gdbregs.regs32[GDB32_FS] !=
+ context->readMiscRegNoEffect(MISCREG_FS)) {
+ warn("Remote gdb: Ignoring update to FS.\n");
+ }
+ if (gdbregs.regs32[GDB32_GS] !=
+ context->readMiscRegNoEffect(MISCREG_GS)) {
+ warn("Remote gdb: Ignoring update to GS.\n");
+ }
+ }
}
-void RemoteGDB::clearSingleStep()
+void
+RemoteGDB::clearSingleStep()
{
- panic("Remote gdb clearSingleStep not implemented in x86!\n");
+ descheduleInstCommitEvent(&singleStepEvent);
}
-void RemoteGDB::setSingleStep()
+void
+RemoteGDB::setSingleStep()
{
- panic("Remoge gdb setSingleStep not implemented in x86!\n");
+ if (!singleStepEvent.scheduled())
+ scheduleInstCommitEvent(&singleStepEvent, 1);
}
diff --git a/src/arch/x86/remote_gdb.hh b/src/arch/x86/remote_gdb.hh
index f8b15a818..b654fc2f8 100644
--- a/src/arch/x86/remote_gdb.hh
+++ b/src/arch/x86/remote_gdb.hh
@@ -1,4 +1,5 @@
/*
+ * Copyright 2014 Google, Inc.
* Copyright (c) 2007 The Hewlett-Packard Development Company
* All rights reserved.
*
@@ -40,6 +41,8 @@
#ifndef __ARCH_X86_REMOTEGDB_HH__
#define __ARCH_X86_REMOTEGDB_HH__
+#include <algorithm>
+
#include "arch/x86/types.hh"
#include "base/remote_gdb.hh"
@@ -48,29 +51,98 @@ class ThreadContext;
namespace X86ISA
{
- class RemoteGDB : public BaseRemoteGDB
+class RemoteGDB : public BaseRemoteGDB
+{
+ public:
+ enum
{
- protected:
- enum RegisterContants
- {
- NumGDBRegs
- //XXX fill this in
- };
+ GDB32_EAX,
+ GDB32_ECX,
+ GDB32_EDX,
+ GDB32_EBX,
+ GDB32_ESP,
+ GDB32_EBP,
+ GDB32_ESI,
+ GDB32_EDI,
+ GDB32_EIP,
+ GDB32_EFLAGS,
+ GDB32_CS,
+ GDB32_SS,
+ GDB32_DS,
+ GDB32_ES,
+ GDB32_FS,
+ GDB32_GS,
- public:
- RemoteGDB(System *system, ThreadContext *context);
+ GDB32_NUMREGS
+ };
+
+ enum
+ {
+ GDB64_RAX,
+ GDB64_RBX,
+ GDB64_RCX,
+ GDB64_RDX,
+ GDB64_RSI,
+ GDB64_RDI,
+ GDB64_RBP,
+ GDB64_RSP,
+ GDB64_R8,
+ GDB64_R9,
+ GDB64_R10,
+ GDB64_R11,
+ GDB64_R12,
+ GDB64_R13,
+ GDB64_R14,
+ GDB64_R15,
+ GDB64_RIP,
+ // These indices index into the reg cache treated as an array of 32
+ // bit integers. The next index is one beyond the previous, and then
+ // scaled up from an index into an array of 64 bit integers.
+ GDB64_RFLAGS_32 = (GDB64_RIP + 1) * 2,
+ GDB64_CS_32,
+ GDB64_SS_32,
+ GDB64_DS_32,
+ GDB64_ES_32,
+ GDB64_FS_32,
+ GDB64_GS_32,
+
+ // Scale the end index count back down (rounded up) to be for an
+ // array of 64 bit integers.
+ GDB64_NUMREGS = (GDB64_GS_32 + 1) / 2 + 1
+ };
- bool acc(Addr addr, size_t len);
+ RemoteGDB(System *system, ThreadContext *context);
+ bool acc(Addr addr, size_t len);
+
+ protected:
+ class SingleStepEvent : public Event
+ {
protected:
- void getregs();
- void setregs();
+ RemoteGDB *gdb;
- void clearSingleStep();
- void setSingleStep();
+ public:
+ SingleStepEvent(RemoteGDB *g) : gdb(g)
+ {}
- Addr nextBkpt;
+ void process();
};
+
+ SingleStepEvent singleStepEvent;
+
+ void getregs();
+ void setregs();
+
+ void clearSingleStep();
+ void setSingleStep();
+
+ bool checkBpLen(size_t len) { return len == 1; }
+};
+
+const int GDB_REG_BYTES =
+ std::max(RemoteGDB::GDB32_NUMREGS * sizeof(uint32_t),
+ RemoteGDB::GDB64_NUMREGS * sizeof(uint64_t));
+
}
#endif // __ARCH_X86_REMOTEGDB_HH__