Extend CpuState interface.

- Add SetInstructionPointer() to allow an outside updates.
- Add Clone() to request a duplicate of the current state object.
- Add UpdateDebugState() to take a debug cpu state structure matching
the current architecture and update its registers with the values from
the cpu state object.
This commit is contained in:
Rene Gollent 2013-05-16 21:22:24 -04:00
parent 21f6b3ea28
commit fe3e87c2a8
5 changed files with 149 additions and 4 deletions

View File

@ -21,13 +21,22 @@ class CpuState : public BReferenceable {
public:
virtual ~CpuState();
virtual status_t Clone(CpuState*& _clone) const = 0;
virtual status_t UpdateDebugState(void* state, size_t size)
const = 0;
virtual target_addr_t InstructionPointer() const = 0;
virtual void SetInstructionPointer(
target_addr_t address) = 0;
virtual target_addr_t StackFramePointer() const = 0;
virtual target_addr_t StackPointer() const = 0;
virtual bool GetRegisterValue(const Register* reg,
BVariant& _value) const = 0;
virtual bool SetRegisterValue(const Register* reg,
const BVariant& value) = 0;
};

View File

@ -1,11 +1,15 @@
/*
* Copyright 2009-2012, Ingo Weinhold, ingo_weinhold@gmx.de.
* Copyright 2011, Rene Gollent, rene@gollent.com.
* Copyright 2011-2013, Rene Gollent, rene@gollent.com.
* Distributed under the terms of the MIT License.
*/
#include "CpuStateX86.h"
#include <new>
#include <string.h>
#include "Register.h"
@ -47,6 +51,53 @@ CpuStateX86::~CpuStateX86()
}
status_t
CpuStateX86::Clone(CpuState*& _clone) const
{
CpuStateX86* newState = new(std::nothrow) CpuStateX86();
if (newState == NULL)
return B_NO_MEMORY;
memcpy(newState->fIntRegisters, fIntRegisters, sizeof(fIntRegisters));
newState->fSetRegisters = fSetRegisters;
newState->fInterruptVector = fInterruptVector;
_clone = newState;
return B_OK;
}
status_t
CpuStateX86::UpdateDebugState(void* state, size_t size) const
{
if (size != sizeof(x86_debug_cpu_state))
return B_BAD_VALUE;
x86_debug_cpu_state* x86State = (x86_debug_cpu_state*)state;
x86State->eip = InstructionPointer();
x86State->user_esp = StackPointer();
x86State->ebp = StackFramePointer();
x86State->eax = IntRegisterValue(X86_REGISTER_EAX);
x86State->ebx = IntRegisterValue(X86_REGISTER_EBX);
x86State->ecx = IntRegisterValue(X86_REGISTER_ECX);
x86State->edx = IntRegisterValue(X86_REGISTER_EDX);
x86State->esi = IntRegisterValue(X86_REGISTER_ESI);
x86State->edi = IntRegisterValue(X86_REGISTER_EDI);
x86State->cs = IntRegisterValue(X86_REGISTER_CS);
x86State->ds = IntRegisterValue(X86_REGISTER_DS);
x86State->es = IntRegisterValue(X86_REGISTER_ES);
x86State->fs = IntRegisterValue(X86_REGISTER_FS);
x86State->gs = IntRegisterValue(X86_REGISTER_GS);
x86State->user_ss = IntRegisterValue(X86_REGISTER_SS);
x86State->vector = fInterruptVector;
return B_OK;
}
target_addr_t
CpuStateX86::InstructionPointer() const
{
@ -55,6 +106,13 @@ CpuStateX86::InstructionPointer() const
}
void
CpuStateX86::SetInstructionPointer(target_addr_t address)
{
SetIntRegister(X86_REGISTER_EIP, (uint32)address);
}
target_addr_t
CpuStateX86::StackFramePointer() const
{

View File

@ -1,6 +1,6 @@
/*
* Copyright 2009-2012, Ingo Weinhold, ingo_weinhold@gmx.de.
* Copyright 2011, Rene Gollent, rene@gollent.com.
* Copyright 2011-2013, Rene Gollent, rene@gollent.com.
* Distributed under the terms of the MIT License.
*/
#ifndef CPU_STATE_X86_H
@ -44,7 +44,14 @@ public:
CpuStateX86(const x86_debug_cpu_state& state);
virtual ~CpuStateX86();
virtual status_t Clone(CpuState*& _clone) const;
virtual status_t UpdateDebugState(void* state, size_t size)
const;
virtual target_addr_t InstructionPointer() const;
virtual void SetInstructionPointer(target_addr_t address);
virtual target_addr_t StackFramePointer() const;
virtual target_addr_t StackPointer() const;
virtual bool GetRegisterValue(const Register* reg,

View File

@ -1,12 +1,16 @@
/*
* Copyright 2012, Alex Smith, alex@alex-smith.me.uk.
* Copyright 2009-2012, Ingo Weinhold, ingo_weinhold@gmx.de.
* Copyright 2011, Rene Gollent, rene@gollent.com.
* Copyright 2011-2013, Rene Gollent, rene@gollent.com.
* Distributed under the terms of the MIT License.
*/
#include "CpuStateX8664.h"
#include <new>
#include <string.h>
#include "Register.h"
@ -52,6 +56,59 @@ CpuStateX8664::~CpuStateX8664()
}
status_t
CpuStateX8664::Clone(CpuState*& _clone) const
{
CpuStateX8664* newState = new(std::nothrow) CpuStateX8664();
if (newState == NULL)
return B_NO_MEMORY;
memcpy(newState->fIntRegisters, fIntRegisters, sizeof(fIntRegisters));
newState->fSetRegisters = fSetRegisters;
_clone = newState;
return B_OK;
}
status_t
CpuStateX8664::UpdateDebugState(void* state, size_t size) const
{
if (size != sizeof(x86_64_debug_cpu_state))
return B_BAD_VALUE;
x86_64_debug_cpu_state* x64State = (x86_64_debug_cpu_state*)state;
x64State->rip = InstructionPointer();
x64State->rsp = StackPointer();
x64State->rbp = StackFramePointer();
x64State->rax = IntRegisterValue(X86_64_REGISTER_RAX);
x64State->rbx = IntRegisterValue(X86_64_REGISTER_RBX);
x64State->rcx = IntRegisterValue(X86_64_REGISTER_RCX);
x64State->rdx = IntRegisterValue(X86_64_REGISTER_RDX);
x64State->rsi = IntRegisterValue(X86_64_REGISTER_RSI);
x64State->rdi = IntRegisterValue(X86_64_REGISTER_RDI);
x64State->r8 = IntRegisterValue(X86_64_REGISTER_R8);
x64State->r9 = IntRegisterValue(X86_64_REGISTER_R9);
x64State->r10 = IntRegisterValue(X86_64_REGISTER_R10);
x64State->r11 = IntRegisterValue(X86_64_REGISTER_R11);
x64State->r12 = IntRegisterValue(X86_64_REGISTER_R12);
x64State->r13 = IntRegisterValue(X86_64_REGISTER_R13);
x64State->r14 = IntRegisterValue(X86_64_REGISTER_R14);
x64State->r15 = IntRegisterValue(X86_64_REGISTER_R15);
x64State->cs = IntRegisterValue(X86_64_REGISTER_CS);
x64State->ds = IntRegisterValue(X86_64_REGISTER_DS);
x64State->es = IntRegisterValue(X86_64_REGISTER_ES);
x64State->fs = IntRegisterValue(X86_64_REGISTER_FS);
x64State->gs = IntRegisterValue(X86_64_REGISTER_GS);
x64State->ss = IntRegisterValue(X86_64_REGISTER_SS);
return B_OK;
}
target_addr_t
CpuStateX8664::InstructionPointer() const
{
@ -60,6 +117,13 @@ CpuStateX8664::InstructionPointer() const
}
void
CpuStateX8664::SetInstructionPointer(target_addr_t address)
{
SetIntRegister(X86_64_REGISTER_RIP, address);
}
target_addr_t
CpuStateX8664::StackFramePointer() const
{

View File

@ -1,7 +1,7 @@
/*
* Copyright 2012, Alex Smith, alex@alex-smith.me.uk.
* Copyright 2009-2012, Ingo Weinhold, ingo_weinhold@gmx.de.
* Copyright 2011, Rene Gollent, rene@gollent.com.
* Copyright 2011-2013, Rene Gollent, rene@gollent.com.
* Distributed under the terms of the MIT License.
*/
#ifndef CPU_STATE_X86_64_H
@ -54,7 +54,14 @@ public:
CpuStateX8664(const x86_64_debug_cpu_state& state);
virtual ~CpuStateX8664();
virtual status_t Clone(CpuState*& _clone) const;
virtual status_t UpdateDebugState(void* state, size_t size)
const;
virtual target_addr_t InstructionPointer() const;
virtual void SetInstructionPointer(target_addr_t address);
virtual target_addr_t StackFramePointer() const;
virtual target_addr_t StackPointer() const;
virtual bool GetRegisterValue(const Register* reg,