diff options
Diffstat (limited to 'src/arch/x86')
-rw-r--r-- | src/arch/x86/remote_gdb.cc | 253 | ||||
-rw-r--r-- | src/arch/x86/remote_gdb.hh | 141 |
2 files changed, 199 insertions, 195 deletions
diff --git a/src/arch/x86/remote_gdb.cc b/src/arch/x86/remote_gdb.cc index dd96037e0..99800385a 100644 --- a/src/arch/x86/remote_gdb.cc +++ b/src/arch/x86/remote_gdb.cc @@ -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 */ #include <sys/signal.h> @@ -54,6 +56,7 @@ #include "base/trace.hh" #include "cpu/base.hh" #include "cpu/thread_context.hh" +#include "debug/GDBAcc.hh" #include "mem/page_table.hh" #include "sim/full_system.hh" @@ -61,7 +64,7 @@ using namespace std; using namespace X86ISA; RemoteGDB::RemoteGDB(System *_system, ThreadContext *c) : - BaseRemoteGDB(_system, c, GDB_REG_BYTES) + BaseRemoteGDB(_system, c) {} bool @@ -88,138 +91,130 @@ RemoteGDB::acc(Addr va, size_t len) } } -void -RemoteGDB::getregs() +RemoteGDB::BaseGdbRegCache* +RemoteGDB::gdbRegs() { 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); - } + if (m5reg.submode == SixtyFourBitMode) + return new AMD64GdbRegCache(this); + else + return new X86GdbRegCache(this); } + + void -RemoteGDB::setregs() +RemoteGDB::AMD64GdbRegCache::getRegs(ThreadContext *context) { - 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"); - } - } + DPRINTF(GDBAcc, "getRegs in remotegdb \n"); + r.rax = context->readIntReg(INTREG_RAX); + r.rbx = context->readIntReg(INTREG_RBX); + r.rcx = context->readIntReg(INTREG_RCX); + r.rdx = context->readIntReg(INTREG_RDX); + r.rsi = context->readIntReg(INTREG_RSI); + r.rdi = context->readIntReg(INTREG_RDI); + r.rbp = context->readIntReg(INTREG_RBP); + r.rsp = context->readIntReg(INTREG_RSP); + r.r8 = context->readIntReg(INTREG_R8); + r.r9 = context->readIntReg(INTREG_R9); + r.r10 = context->readIntReg(INTREG_R10); + r.r11 = context->readIntReg(INTREG_R11); + r.r12 = context->readIntReg(INTREG_R12); + r.r13 = context->readIntReg(INTREG_R13); + r.r14 = context->readIntReg(INTREG_R14); + r.r15 = context->readIntReg(INTREG_R15); + r.rip = context->pcState().pc(); + r.eflags = context->readMiscRegNoEffect(MISCREG_RFLAGS); + r.cs = context->readMiscRegNoEffect(MISCREG_CS); + r.ss = context->readMiscRegNoEffect(MISCREG_SS); + r.ds = context->readMiscRegNoEffect(MISCREG_DS); + r.es = context->readMiscRegNoEffect(MISCREG_ES); + r.fs = context->readMiscRegNoEffect(MISCREG_FS); + r.gs = context->readMiscRegNoEffect(MISCREG_GS); +} + +void +RemoteGDB::X86GdbRegCache::getRegs(ThreadContext *context) +{ + DPRINTF(GDBAcc, "getRegs in remotegdb \n"); + r.eax = context->readIntReg(INTREG_RAX); + r.ecx = context->readIntReg(INTREG_RCX); + r.edx = context->readIntReg(INTREG_RDX); + r.ebx = context->readIntReg(INTREG_RBX); + r.esp = context->readIntReg(INTREG_RSP); + r.ebp = context->readIntReg(INTREG_RBP); + r.esi = context->readIntReg(INTREG_RSI); + r.edi = context->readIntReg(INTREG_RDI); + r.eip = context->pcState().pc(); + r.eflags = context->readMiscRegNoEffect(MISCREG_RFLAGS); + r.cs = context->readMiscRegNoEffect(MISCREG_CS); + r.ss = context->readMiscRegNoEffect(MISCREG_SS); + r.ds = context->readMiscRegNoEffect(MISCREG_DS); + r.es = context->readMiscRegNoEffect(MISCREG_ES); + r.fs = context->readMiscRegNoEffect(MISCREG_FS); + r.gs = context->readMiscRegNoEffect(MISCREG_GS); +} + +void +RemoteGDB::AMD64GdbRegCache::setRegs(ThreadContext *context) const +{ + DPRINTF(GDBAcc, "setRegs in remotegdb \n"); + context->setIntReg(INTREG_RAX, r.rax); + context->setIntReg(INTREG_RBX, r.rbx); + context->setIntReg(INTREG_RCX, r.rcx); + context->setIntReg(INTREG_RDX, r.rdx); + context->setIntReg(INTREG_RSI, r.rsi); + context->setIntReg(INTREG_RDI, r.rdi); + context->setIntReg(INTREG_RBP, r.rbp); + context->setIntReg(INTREG_RSP, r.rsp); + context->setIntReg(INTREG_R8, r.r8); + context->setIntReg(INTREG_R9, r.r9); + context->setIntReg(INTREG_R10, r.r10); + context->setIntReg(INTREG_R11, r.r11); + context->setIntReg(INTREG_R12, r.r12); + context->setIntReg(INTREG_R13, r.r13); + context->setIntReg(INTREG_R14, r.r14); + context->setIntReg(INTREG_R15, r.r15); + context->pcState(r.rip); + context->setMiscReg(MISCREG_RFLAGS, r.eflags); + if (r.cs != context->readMiscRegNoEffect(MISCREG_CS)) + warn("Remote gdb: Ignoring update to CS.\n"); + if (r.ss != context->readMiscRegNoEffect(MISCREG_SS)) + warn("Remote gdb: Ignoring update to SS.\n"); + if (r.ds != context->readMiscRegNoEffect(MISCREG_DS)) + warn("Remote gdb: Ignoring update to DS.\n"); + if (r.es != context->readMiscRegNoEffect(MISCREG_ES)) + warn("Remote gdb: Ignoring update to ES.\n"); + if (r.fs != context->readMiscRegNoEffect(MISCREG_FS)) + warn("Remote gdb: Ignoring update to FS.\n"); + if (r.gs != context->readMiscRegNoEffect(MISCREG_GS)) + warn("Remote gdb: Ignoring update to GS.\n"); +} + +void +RemoteGDB::X86GdbRegCache::setRegs(ThreadContext *context) const +{ + DPRINTF(GDBAcc, "setRegs in remotegdb \n"); + context->setIntReg(INTREG_RAX, r.eax); + context->setIntReg(INTREG_RCX, r.ecx); + context->setIntReg(INTREG_RDX, r.edx); + context->setIntReg(INTREG_RBX, r.ebx); + context->setIntReg(INTREG_RSP, r.esp); + context->setIntReg(INTREG_RBP, r.ebp); + context->setIntReg(INTREG_RSI, r.esi); + context->setIntReg(INTREG_RDI, r.edi); + context->pcState(r.eip); + context->setMiscReg(MISCREG_RFLAGS, r.eflags); + if (r.cs != context->readMiscRegNoEffect(MISCREG_CS)) + warn("Remote gdb: Ignoring update to CS.\n"); + if (r.ss != context->readMiscRegNoEffect(MISCREG_SS)) + warn("Remote gdb: Ignoring update to SS.\n"); + if (r.ds != context->readMiscRegNoEffect(MISCREG_DS)) + warn("Remote gdb: Ignoring update to DS.\n"); + if (r.es != context->readMiscRegNoEffect(MISCREG_ES)) + warn("Remote gdb: Ignoring update to ES.\n"); + if (r.fs != context->readMiscRegNoEffect(MISCREG_FS)) + warn("Remote gdb: Ignoring update to FS.\n"); + if (r.gs != context->readMiscRegNoEffect(MISCREG_GS)) + warn("Remote gdb: Ignoring update to GS.\n"); } 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__ |