summaryrefslogtreecommitdiff
path: root/src/arch/x86/remote_gdb.hh
diff options
context:
space:
mode:
authorBoris Shingarov <shingarov@labware.com>2015-12-18 15:12:07 -0600
committerBoris Shingarov <shingarov@labware.com>2015-12-18 15:12:07 -0600
commitd765dbf22cb3242c055b19b797b0f4cb39a43aae (patch)
tree55fade43c664a78e55823cdc43f7bcec1bf663a9 /src/arch/x86/remote_gdb.hh
parentb5a54eb64ebce9c217c1d44cc93aebb7cb508c6d (diff)
downloadgem5-d765dbf22cb3242c055b19b797b0f4cb39a43aae.tar.xz
arm: remote GDB: rationalize structure of register offsets
Currently, the wire format of register values in g- and G-packets is modelled using a union of uint8/16/32/64 arrays. The offset positions of each register are expressed as a "register count" scaled according to the width of the register in question. This results in counter- intuitive and error-prone "register count arithmetic", and some formats would even be altogether unrepresentable in such model, e.g. a 64-bit register following a 32-bit one would have a fractional index in the regs64 array. Another difficulty is that the array is allocated before the actual architecture of the workload is known (and therefore before the correct size for the array can be calculated). With this patch I propose a simpler mechanism for expressing the register set structure. In the new code, GdbRegCache is an abstract class; its subclasses contain straightforward structs reflecting the register representation. The determination whether to use e.g. the AArch32 vs. AArch64 register set (or SPARCv8 vs SPARCv9, etc.) is made by polymorphically dispatching getregs() to the concrete subclass. The subclass is not instantiated until it is needed for actual g-/G-packet processing, when the mode is already known. This patch is not meant to be merged in on its own, because it changes the contract between src/base/remote_gdb.* and src/arch/*/remote_gdb.*, so as it stands right now, it would break the other architectures. In this patch only the base and the ARM code are provided for review; once we agree on the structure, I will provide src/arch/*/remote_gdb.* for the other architectures; those patches could then be merged in together. Review Request: http://reviews.gem5.org/r/3207/ Pushed by Joel Hestness <jthestness@gmail.com>
Diffstat (limited to 'src/arch/x86/remote_gdb.hh')
-rw-r--r--src/arch/x86/remote_gdb.hh141
1 files changed, 75 insertions, 66 deletions
diff --git a/src/arch/x86/remote_gdb.hh b/src/arch/x86/remote_gdb.hh
index 991452f74..5696e3dc7 100644
--- a/src/arch/x86/remote_gdb.hh
+++ b/src/arch/x86/remote_gdb.hh
@@ -1,4 +1,5 @@
/*
+ * Copyright 2015 LabWare
* Copyright 2014 Google, Inc.
* Copyright (c) 2007 The Hewlett-Packard Development Company
* All rights reserved.
@@ -36,6 +37,7 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors: Gabe Black
+ * Boris Shingarov
*/
#ifndef __ARCH_X86_REMOTEGDB_HH__
@@ -53,79 +55,86 @@ namespace X86ISA
{
class RemoteGDB : public BaseRemoteGDB
{
- public:
- enum
+ protected:
+ bool acc(Addr addr, size_t len);
+ bool checkBpLen(size_t len) { return len == 1; }
+ class X86GdbRegCache : public BaseGdbRegCache
{
- 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,
-
- GDB32_NUMREGS
+ using BaseGdbRegCache::BaseGdbRegCache;
+ private:
+ struct {
+ uint32_t eax;
+ uint32_t ecx;
+ uint32_t edx;
+ uint32_t ebx;
+ uint32_t esp;
+ uint32_t ebp;
+ uint32_t esi;
+ uint32_t edi;
+ uint32_t eip;
+ uint32_t eflags;
+ uint32_t cs;
+ uint32_t ss;
+ uint32_t ds;
+ uint32_t es;
+ uint32_t fs;
+ uint32_t gs;
+ } r;
+ public:
+ char *data() const { return (char *)&r; }
+ size_t size() const { return sizeof(r); }
+ void getRegs(ThreadContext*);
+ void setRegs(ThreadContext*) const;
+ const std::string name() const { return gdb->name() + ".X86GdbRegCache"; }
};
- enum
+ class AMD64GdbRegCache : public BaseGdbRegCache
{
- 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
+ using BaseGdbRegCache::BaseGdbRegCache;
+ private:
+ struct {
+ uint64_t rax;
+ uint64_t rbx;
+ uint64_t rcx;
+ uint64_t rdx;
+ uint64_t rsi;
+ uint64_t rdi;
+ uint64_t rbp;
+ uint64_t rsp;
+ uint64_t r8;
+ uint64_t r9;
+ uint64_t r10;
+ uint64_t r11;
+ uint64_t r12;
+ uint64_t r13;
+ uint64_t r14;
+ uint64_t r15;
+ uint64_t rip;
+ uint32_t eflags;
+ uint32_t cs;
+ uint32_t ss;
+ uint32_t ds;
+ uint32_t es;
+ uint32_t fs;
+ uint32_t gs;
+ /*
+ * We do not model st[], FPU status regs, xmm[] etc.
+ * While it's not ok to have G-packets larger than what gdb
+ * knows about, it is ok to have smaller ones.
+ */
+ } r;
+ public:
+ char *data() const { return (char *)&r; }
+ size_t size() const { return sizeof(r); }
+ void getRegs(ThreadContext*);
+ void setRegs(ThreadContext*) const;
+ const std::string name() const { return gdb->name() + ".AMD64GdbRegCache"; }
};
+ public:
RemoteGDB(System *system, ThreadContext *context);
-
- bool acc(Addr addr, size_t len);
-
- protected:
- void getregs();
- void setregs();
-
- bool checkBpLen(size_t len) { return len == 1; }
+ BaseGdbRegCache *gdbRegs();
};
-
-const int GDB_REG_BYTES M5_VAR_USED =
- std::max(RemoteGDB::GDB32_NUMREGS * sizeof(uint32_t),
- RemoteGDB::GDB64_NUMREGS * sizeof(uint64_t));
-
-}
+} // namespace X86ISA
#endif // __ARCH_X86_REMOTEGDB_HH__