summaryrefslogtreecommitdiff
path: root/src/arch/x86/remote_gdb.hh
diff options
context:
space:
mode:
authorGabe Black <gabeblack@google.com>2014-12-05 22:36:16 -0800
committerGabe Black <gabeblack@google.com>2014-12-05 22:36:16 -0800
commitfb07d43b1a4a903fb2e51b41685eb5814d9f9e11 (patch)
tree0e44d7e5bc796da39ce7cb4ecb908e787adba978 /src/arch/x86/remote_gdb.hh
parent16c9b41616312bfef0b5859f7cebe24e8c17d9da (diff)
downloadgem5-fb07d43b1a4a903fb2e51b41685eb5814d9f9e11.tar.xz
x86: Implement a remote GDB stub.
This stub should allow remote debugging of 32 bit and 64 bit targets. Single stepping seems to work, as do breakpoints. If both breakpoints and single stepping affect an instruction, gdb will stop at the instruction twice before continuing. That's a little surprising, but is generally harmless.
Diffstat (limited to 'src/arch/x86/remote_gdb.hh')
-rw-r--r--src/arch/x86/remote_gdb.hh102
1 files changed, 87 insertions, 15 deletions
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__