More work on the architecture abstraction, particularly regarding information
about what registers the architecture has and how to get them from the CpuState. Implemented the respective x86 part. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@31109 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
3c4cb05b95
commit
c42fe1eb57
@ -32,6 +32,7 @@ Application Debugger :
|
||||
# arch
|
||||
Architecture.cpp
|
||||
CpuState.cpp
|
||||
Register.cpp
|
||||
StackFrame.cpp
|
||||
StackTrace.cpp
|
||||
|
||||
|
@ -16,3 +16,10 @@ Architecture::Architecture(DebuggerInterface* debuggerInterface)
|
||||
Architecture::~Architecture()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
Architecture::Init()
|
||||
{
|
||||
return B_OK;
|
||||
}
|
||||
|
@ -12,6 +12,7 @@
|
||||
|
||||
class CpuState;
|
||||
class DebuggerInterface;
|
||||
class Register;
|
||||
|
||||
|
||||
class Architecture : public Referenceable {
|
||||
@ -20,6 +21,11 @@ public:
|
||||
DebuggerInterface* debuggerInterface);
|
||||
virtual ~Architecture();
|
||||
|
||||
virtual status_t Init();
|
||||
|
||||
virtual int32 CountRegisters() const = 0;
|
||||
virtual const Register* Registers() const = 0;
|
||||
|
||||
virtual status_t CreateCpuState(const void* cpuStateData,
|
||||
size_t size, CpuState*& _state) = 0;
|
||||
|
||||
|
@ -9,10 +9,18 @@
|
||||
|
||||
#include <Referenceable.h>
|
||||
|
||||
#include "Variant.h"
|
||||
|
||||
|
||||
class Register;
|
||||
|
||||
|
||||
class CpuState : public Referenceable {
|
||||
public:
|
||||
virtual ~CpuState();
|
||||
|
||||
virtual bool GetRegisterValue(const Register* reg,
|
||||
Variant& _value) = 0;
|
||||
};
|
||||
|
||||
|
||||
|
29
src/apps/debugger/arch/Register.cpp
Normal file
29
src/apps/debugger/arch/Register.cpp
Normal file
@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
#include "Register.h"
|
||||
|
||||
|
||||
Register::Register(int32 index, const char* name, register_format format,
|
||||
uint32 bitSize, register_type type)
|
||||
:
|
||||
fIndex(index),
|
||||
fName(name),
|
||||
fFormat(format),
|
||||
fBitSize(bitSize),
|
||||
fType(type)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
Register::Register(const Register& other)
|
||||
:
|
||||
fIndex(other.fIndex),
|
||||
fName(other.fName),
|
||||
fFormat(other.fFormat),
|
||||
fBitSize(other.fBitSize),
|
||||
fType(other.fType)
|
||||
{
|
||||
}
|
49
src/apps/debugger/arch/Register.h
Normal file
49
src/apps/debugger/arch/Register.h
Normal file
@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef REGISTER_H
|
||||
#define REGISTER_H
|
||||
|
||||
#include <SupportDefs.h>
|
||||
|
||||
|
||||
enum register_format {
|
||||
REGISTER_FORMAT_INTEGER,
|
||||
REGISTER_FORMAT_FLOAT
|
||||
};
|
||||
|
||||
enum register_type {
|
||||
REGISTER_TYPE_PROGRAM_COUNTER,
|
||||
REGISTER_TYPE_STACK_POINTER,
|
||||
REGISTER_TYPE_GENERAL_PURPOSE,
|
||||
REGISTER_TYPE_SPECIAL_PURPOSE,
|
||||
REGISTER_TYPE_EXTENDED
|
||||
};
|
||||
|
||||
|
||||
class Register {
|
||||
public:
|
||||
Register(int32 index, const char* name,
|
||||
register_format format, uint32 bitSize,
|
||||
register_type type);
|
||||
// name will not be cloned
|
||||
Register(const Register& other);
|
||||
|
||||
int32 Index() const { return fIndex; }
|
||||
const char* Name() const { return fName; }
|
||||
register_format Format() const { return fFormat; }
|
||||
uint32 BitSize() const { return fBitSize; }
|
||||
register_type Type() const { return fType; }
|
||||
|
||||
private:
|
||||
int32 fIndex;
|
||||
const char* fName;
|
||||
register_format fFormat;
|
||||
uint32 fBitSize;
|
||||
register_type fType;
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif // REGISTER_H
|
@ -22,6 +22,65 @@ ArchitectureX86::~ArchitectureX86()
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
ArchitectureX86::Init()
|
||||
{
|
||||
try {
|
||||
_AddIntegerRegister(X86_REGISTER_EIP, "eip", 32,
|
||||
REGISTER_TYPE_PROGRAM_COUNTER);
|
||||
_AddIntegerRegister(X86_REGISTER_ESP, "esp", 32,
|
||||
REGISTER_TYPE_STACK_POINTER);
|
||||
_AddIntegerRegister(X86_REGISTER_EBP, "ebp", 32,
|
||||
REGISTER_TYPE_GENERAL_PURPOSE);
|
||||
|
||||
_AddIntegerRegister(X86_REGISTER_EAX, "eax", 32,
|
||||
REGISTER_TYPE_GENERAL_PURPOSE);
|
||||
_AddIntegerRegister(X86_REGISTER_EBX, "ebx", 32,
|
||||
REGISTER_TYPE_GENERAL_PURPOSE);
|
||||
_AddIntegerRegister(X86_REGISTER_ECX, "ecx", 32,
|
||||
REGISTER_TYPE_GENERAL_PURPOSE);
|
||||
_AddIntegerRegister(X86_REGISTER_EDX, "edx", 32,
|
||||
REGISTER_TYPE_GENERAL_PURPOSE);
|
||||
|
||||
_AddIntegerRegister(X86_REGISTER_ESI, "esi", 32,
|
||||
REGISTER_TYPE_GENERAL_PURPOSE);
|
||||
_AddIntegerRegister(X86_REGISTER_EDI, "edi", 32,
|
||||
REGISTER_TYPE_GENERAL_PURPOSE);
|
||||
|
||||
_AddIntegerRegister(X86_REGISTER_CS, "cs", 16,
|
||||
REGISTER_TYPE_SPECIAL_PURPOSE);
|
||||
_AddIntegerRegister(X86_REGISTER_DS, "ds", 16,
|
||||
REGISTER_TYPE_SPECIAL_PURPOSE);
|
||||
_AddIntegerRegister(X86_REGISTER_ES, "es", 16,
|
||||
REGISTER_TYPE_SPECIAL_PURPOSE);
|
||||
_AddIntegerRegister(X86_REGISTER_FS, "fs", 16,
|
||||
REGISTER_TYPE_SPECIAL_PURPOSE);
|
||||
_AddIntegerRegister(X86_REGISTER_GS, "gs", 16,
|
||||
REGISTER_TYPE_SPECIAL_PURPOSE);
|
||||
_AddIntegerRegister(X86_REGISTER_SS, "ss", 16,
|
||||
REGISTER_TYPE_SPECIAL_PURPOSE);
|
||||
} catch (std::bad_alloc) {
|
||||
return B_NO_MEMORY;
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
int32
|
||||
ArchitectureX86::CountRegisters() const
|
||||
{
|
||||
return fRegisters.Count();
|
||||
}
|
||||
|
||||
|
||||
const Register*
|
||||
ArchitectureX86::Registers() const
|
||||
{
|
||||
return fRegisters.Elements();
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
ArchitectureX86::CreateCpuState(const void* cpuStateData, size_t size,
|
||||
CpuState*& _state)
|
||||
@ -37,3 +96,20 @@ ArchitectureX86::CreateCpuState(const void* cpuStateData, size_t size,
|
||||
_state = state;
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ArchitectureX86::_AddRegister(int32 index, const char* name,
|
||||
register_format format, uint32 bitSize, register_type type)
|
||||
{
|
||||
if (!fRegisters.Add(Register(index, name, format, bitSize, type)))
|
||||
throw std::bad_alloc();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ArchitectureX86::_AddIntegerRegister(int32 index, const char* name,
|
||||
uint32 bitSize, register_type type)
|
||||
{
|
||||
_AddRegister(index, name, REGISTER_FORMAT_INTEGER, bitSize, type);
|
||||
}
|
||||
|
@ -6,6 +6,8 @@
|
||||
#define ARCHITECTURE_X86_H
|
||||
|
||||
#include "Architecture.h"
|
||||
#include "Array.h"
|
||||
#include "Register.h"
|
||||
|
||||
|
||||
class ArchitectureX86 : public Architecture {
|
||||
@ -14,8 +16,24 @@ public:
|
||||
DebuggerInterface* debuggerInterface);
|
||||
virtual ~ArchitectureX86();
|
||||
|
||||
virtual status_t Init();
|
||||
|
||||
virtual int32 CountRegisters() const;
|
||||
virtual const Register* Registers() const;
|
||||
|
||||
virtual status_t CreateCpuState(const void* cpuStateData,
|
||||
size_t size, CpuState*& _state);
|
||||
|
||||
private:
|
||||
void _AddRegister(int32 index, const char* name,
|
||||
register_format format, uint32 bitSize,
|
||||
register_type type);
|
||||
void _AddIntegerRegister(int32 index,
|
||||
const char* name, uint32 bitSize,
|
||||
register_type type);
|
||||
|
||||
private:
|
||||
Array<Register> fRegisters;
|
||||
};
|
||||
|
||||
|
||||
|
@ -5,14 +5,88 @@
|
||||
|
||||
#include "CpuStateX86.h"
|
||||
|
||||
#include "Register.h"
|
||||
|
||||
|
||||
CpuStateX86::CpuStateX86(const debug_cpu_state_x86& state)
|
||||
:
|
||||
fState(state)
|
||||
fSetRegisters()
|
||||
{
|
||||
SetIntRegister(X86_REGISTER_EIP, state.eip);
|
||||
SetIntRegister(X86_REGISTER_ESP, state.user_esp);
|
||||
SetIntRegister(X86_REGISTER_EBP, state.ebp);
|
||||
SetIntRegister(X86_REGISTER_EAX, state.eax);
|
||||
SetIntRegister(X86_REGISTER_EBX, state.ebx);
|
||||
SetIntRegister(X86_REGISTER_ECX, state.ecx);
|
||||
SetIntRegister(X86_REGISTER_EDX, state.edx);
|
||||
SetIntRegister(X86_REGISTER_ESI, state.esi);
|
||||
SetIntRegister(X86_REGISTER_EDI, state.edi);
|
||||
SetIntRegister(X86_REGISTER_CS, state.cs);
|
||||
SetIntRegister(X86_REGISTER_DS, state.ds);
|
||||
SetIntRegister(X86_REGISTER_ES, state.es);
|
||||
SetIntRegister(X86_REGISTER_FS, state.fs);
|
||||
SetIntRegister(X86_REGISTER_GS, state.gs);
|
||||
SetIntRegister(X86_REGISTER_SS, state.user_ss);
|
||||
}
|
||||
|
||||
|
||||
CpuStateX86::~CpuStateX86()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
CpuStateX86::GetRegisterValue(const Register* reg, Variant& _value)
|
||||
{
|
||||
int32 index = reg->Index();
|
||||
if (!IsRegisterSet(index))
|
||||
return false;
|
||||
|
||||
if (index >= X86_INT_REGISTER_END)
|
||||
return false;
|
||||
|
||||
if (reg->BitSize() == 16)
|
||||
_value.SetTo((uint16)fIntRegisters[index]);
|
||||
else
|
||||
_value.SetTo(fIntRegisters[index]);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
CpuStateX86::IsRegisterSet(int32 index) const
|
||||
{
|
||||
return index >= 0 && index < X86_REGISTER_COUNT && fSetRegisters[index];
|
||||
}
|
||||
|
||||
|
||||
uint32
|
||||
CpuStateX86::IntRegisterValue(int32 index) const
|
||||
{
|
||||
if (!IsRegisterSet(index) || index >= X86_INT_REGISTER_END)
|
||||
return 0;
|
||||
|
||||
return fIntRegisters[index];
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
CpuStateX86::SetIntRegister(int32 index, uint32 value)
|
||||
{
|
||||
if (index < 0 || index >= X86_INT_REGISTER_END)
|
||||
return;
|
||||
|
||||
fIntRegisters[index] = value;
|
||||
fSetRegisters[index] = 1;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
CpuStateX86::UnsetRegister(int32 index)
|
||||
{
|
||||
if (index < 0 || index >= X86_REGISTER_COUNT)
|
||||
return;
|
||||
|
||||
fSetRegisters[index] = 0;
|
||||
}
|
||||
|
@ -5,6 +5,8 @@
|
||||
#ifndef CPU_STATE_X86_H
|
||||
#define CPU_STATE_X86_H
|
||||
|
||||
#include <bitset>
|
||||
|
||||
#include <debugger.h>
|
||||
|
||||
#include "CpuState.h"
|
||||
@ -13,16 +15,50 @@
|
||||
typedef debug_cpu_state debug_cpu_state_x86;
|
||||
// TODO: Should be defined by <debugger.h>!
|
||||
|
||||
enum {
|
||||
X86_REGISTER_EIP = 0,
|
||||
X86_REGISTER_ESP,
|
||||
X86_REGISTER_EBP,
|
||||
|
||||
X86_REGISTER_EAX,
|
||||
X86_REGISTER_EBX,
|
||||
X86_REGISTER_ECX,
|
||||
X86_REGISTER_EDX,
|
||||
|
||||
X86_REGISTER_ESI,
|
||||
X86_REGISTER_EDI,
|
||||
|
||||
X86_REGISTER_CS,
|
||||
X86_REGISTER_DS,
|
||||
X86_REGISTER_ES,
|
||||
X86_REGISTER_FS,
|
||||
X86_REGISTER_GS,
|
||||
X86_REGISTER_SS,
|
||||
|
||||
X86_INT_REGISTER_END,
|
||||
X86_REGISTER_COUNT
|
||||
};
|
||||
|
||||
|
||||
class CpuStateX86 : public CpuState {
|
||||
public:
|
||||
CpuStateX86(const debug_cpu_state_x86& state);
|
||||
virtual ~CpuStateX86();
|
||||
|
||||
const debug_cpu_state_x86 State() const { return fState; }
|
||||
virtual bool GetRegisterValue(const Register* reg,
|
||||
Variant& _value);
|
||||
|
||||
bool IsRegisterSet(int32 index) const;
|
||||
uint32 IntRegisterValue(int32 index) const;
|
||||
void SetIntRegister(int32 index, uint32 value);
|
||||
void UnsetRegister(int32 index);
|
||||
|
||||
private:
|
||||
debug_cpu_state_x86 fState;
|
||||
typedef std::bitset<X86_REGISTER_COUNT> RegisterBitSet;
|
||||
|
||||
private:
|
||||
uint32 fIntRegisters[X86_REGISTER_COUNT];
|
||||
RegisterBitSet fSetRegisters;
|
||||
};
|
||||
|
||||
|
||||
|
@ -254,6 +254,10 @@ DebuggerInterface::Init()
|
||||
if (fArchitecture == NULL)
|
||||
return B_NO_MEMORY;
|
||||
|
||||
status_t error = fArchitecture->Init();
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
|
||||
// create debugger port
|
||||
char buffer[128];
|
||||
snprintf(buffer, sizeof(buffer), "team %ld debugger", fTeamID);
|
||||
@ -271,7 +275,7 @@ DebuggerInterface::Init()
|
||||
if (fDebugContextPool == NULL)
|
||||
return B_NO_MEMORY;
|
||||
|
||||
status_t error = fDebugContextPool->Init();
|
||||
error = fDebugContextPool->Init();
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
|
||||
@ -425,13 +429,8 @@ DebuggerInterface::GetCpuState(thread_id thread, CpuState*& _state)
|
||||
if (reply.error != B_OK)
|
||||
return reply.error;
|
||||
|
||||
// TODO: Correctly create the state...
|
||||
CpuState* state = new(std::nothrow) CpuState;
|
||||
if (state == NULL)
|
||||
return B_NO_MEMORY;
|
||||
|
||||
_state = state;
|
||||
return B_OK;
|
||||
return fArchitecture->CreateCpuState(&reply.cpu_state,
|
||||
sizeof(debug_cpu_state), _state);
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user