diff --git a/src/apps/debugger/Jamfile b/src/apps/debugger/Jamfile index d0b633127c..0c3650d437 100644 --- a/src/apps/debugger/Jamfile +++ b/src/apps/debugger/Jamfile @@ -32,6 +32,7 @@ Application Debugger : # arch Architecture.cpp CpuState.cpp + Register.cpp StackFrame.cpp StackTrace.cpp diff --git a/src/apps/debugger/arch/Architecture.cpp b/src/apps/debugger/arch/Architecture.cpp index c2ba10eb51..c7b285d060 100644 --- a/src/apps/debugger/arch/Architecture.cpp +++ b/src/apps/debugger/arch/Architecture.cpp @@ -16,3 +16,10 @@ Architecture::Architecture(DebuggerInterface* debuggerInterface) Architecture::~Architecture() { } + + +status_t +Architecture::Init() +{ + return B_OK; +} diff --git a/src/apps/debugger/arch/Architecture.h b/src/apps/debugger/arch/Architecture.h index dec7a6b943..692fdca476 100644 --- a/src/apps/debugger/arch/Architecture.h +++ b/src/apps/debugger/arch/Architecture.h @@ -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; diff --git a/src/apps/debugger/arch/CpuState.h b/src/apps/debugger/arch/CpuState.h index 6b109f2944..28944f7b92 100644 --- a/src/apps/debugger/arch/CpuState.h +++ b/src/apps/debugger/arch/CpuState.h @@ -9,10 +9,18 @@ #include +#include "Variant.h" + + +class Register; + class CpuState : public Referenceable { public: virtual ~CpuState(); + + virtual bool GetRegisterValue(const Register* reg, + Variant& _value) = 0; }; diff --git a/src/apps/debugger/arch/Register.cpp b/src/apps/debugger/arch/Register.cpp new file mode 100644 index 0000000000..2f8449c566 --- /dev/null +++ b/src/apps/debugger/arch/Register.cpp @@ -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) +{ +} diff --git a/src/apps/debugger/arch/Register.h b/src/apps/debugger/arch/Register.h new file mode 100644 index 0000000000..a6b621895b --- /dev/null +++ b/src/apps/debugger/arch/Register.h @@ -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 + + +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 diff --git a/src/apps/debugger/arch/x86/ArchitectureX86.cpp b/src/apps/debugger/arch/x86/ArchitectureX86.cpp index 2189839bd8..5b00983c22 100644 --- a/src/apps/debugger/arch/x86/ArchitectureX86.cpp +++ b/src/apps/debugger/arch/x86/ArchitectureX86.cpp @@ -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); +} diff --git a/src/apps/debugger/arch/x86/ArchitectureX86.h b/src/apps/debugger/arch/x86/ArchitectureX86.h index 98592ba5b5..7ef7638206 100644 --- a/src/apps/debugger/arch/x86/ArchitectureX86.h +++ b/src/apps/debugger/arch/x86/ArchitectureX86.h @@ -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 fRegisters; }; diff --git a/src/apps/debugger/arch/x86/CpuStateX86.cpp b/src/apps/debugger/arch/x86/CpuStateX86.cpp index f31773fdca..7a8513f5fe 100644 --- a/src/apps/debugger/arch/x86/CpuStateX86.cpp +++ b/src/apps/debugger/arch/x86/CpuStateX86.cpp @@ -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; +} diff --git a/src/apps/debugger/arch/x86/CpuStateX86.h b/src/apps/debugger/arch/x86/CpuStateX86.h index e25e095439..c83e0a717d 100644 --- a/src/apps/debugger/arch/x86/CpuStateX86.h +++ b/src/apps/debugger/arch/x86/CpuStateX86.h @@ -5,6 +5,8 @@ #ifndef CPU_STATE_X86_H #define CPU_STATE_X86_H +#include + #include #include "CpuState.h" @@ -13,16 +15,50 @@ typedef debug_cpu_state debug_cpu_state_x86; // TODO: Should be defined by ! +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 RegisterBitSet; + +private: + uint32 fIntRegisters[X86_REGISTER_COUNT]; + RegisterBitSet fSetRegisters; }; diff --git a/src/apps/debugger/debugger_interface/DebuggerInterface.cpp b/src/apps/debugger/debugger_interface/DebuggerInterface.cpp index 82cf1c34e8..6f1a8ce9ff 100644 --- a/src/apps/debugger/debugger_interface/DebuggerInterface.cpp +++ b/src/apps/debugger/debugger_interface/DebuggerInterface.cpp @@ -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); }