* Register:

- Added a type constant describing the format of the register value.
  - Added flag "is callee-preserved" indicating whether the ABI requires the
    register to be preserved by a called function.
* CpuState: Added SetRegisterValue(), made GetRegisterValue() const.
* Added RegisterMap interface for mapping register indices between different
  models.
* Architecture:
  - Added CreateCpuState() version to create a clean CpuState.
  - Added GetDwarfRegisterMaps(), which returns to RegisterMaps, converting
    from and to DWARF register indices.
  - Added ReadValueFromMemory() reading a value from the target team's memory.
    The value type is specified by a type constant and the value return via a
    BVariant.
  - CreateStackTrace: No longer decide whether to adjust the instruction pointer
    of the previous CPU state depending on who created the CPU state. Instead
    compare it with the return address of the next frame. If they are equal it
    obviously has to be adjusted.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@31539 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Ingo Weinhold
2009-07-13 18:45:49 +00:00
parent 3b859de22e
commit 614e1dc42f
12 changed files with 349 additions and 63 deletions
+1
View File
@@ -44,6 +44,7 @@ Application Debugger :
CpuState.cpp CpuState.cpp
InstructionInfo.cpp InstructionInfo.cpp
Register.cpp Register.cpp
RegisterMap.cpp
# arch/x86 # arch/x86
ArchitectureX86.cpp ArchitectureX86.cpp
+5 -7
View File
@@ -52,7 +52,6 @@ Architecture::CreateStackTrace(Team* team,
return B_NO_MEMORY; return B_NO_MEMORY;
ObjectDeleter<StackTrace> stackTraceDeleter(stackTrace); ObjectDeleter<StackTrace> stackTraceDeleter(stackTrace);
bool architectureFrame = false;
StackFrame* frame = NULL; StackFrame* frame = NULL;
while (cpuState != NULL) { while (cpuState != NULL) {
@@ -85,9 +84,10 @@ Architecture::CreateStackTrace(Team* team,
Reference<FunctionInstance> functionReference(function); Reference<FunctionInstance> functionReference(function);
teamLocker.Unlock(); teamLocker.Unlock();
// If the last frame had been created by the architecture, we update the // If the CPU state's instruction pointer is actually the return address
// CPU state. // of the next frame, we let the architecture fix that.
if (architectureFrame) { if (frame != NULL
&& frame->ReturnAddress() == cpuState->InstructionPointer()) {
UpdateStackFrameCpuState(frame, image, UpdateStackFrameCpuState(frame, image,
functionDebugInfo, cpuState); functionDebugInfo, cpuState);
} }
@@ -109,9 +109,7 @@ Architecture::CreateStackTrace(Team* team,
cpuState, frame == NULL, previousFrame, previousCpuState); cpuState, frame == NULL, previousFrame, previousCpuState);
if (error != B_OK) if (error != B_OK)
break; break;
architectureFrame = true; }
} else
architectureFrame = false;
cpuStateReference.SetTo(previousCpuState, true); cpuStateReference.SetTo(previousCpuState, true);
+12
View File
@@ -5,9 +5,11 @@
#ifndef ARCHITECTURE_H #ifndef ARCHITECTURE_H
#define ARCHITECTURE_H #define ARCHITECTURE_H
#include <OS.h> #include <OS.h>
#include <Referenceable.h> #include <Referenceable.h>
#include <Variant.h>
#include "Types.h" #include "Types.h"
@@ -19,6 +21,7 @@ class Image;
class ImageDebugInfoProvider; class ImageDebugInfoProvider;
class InstructionInfo; class InstructionInfo;
class Register; class Register;
class RegisterMap;
class StackFrame; class StackFrame;
class StackTrace; class StackTrace;
class Statement; class Statement;
@@ -36,6 +39,11 @@ public:
virtual int32 CountRegisters() const = 0; virtual int32 CountRegisters() const = 0;
virtual const Register* Registers() const = 0; virtual const Register* Registers() const = 0;
virtual status_t GetDwarfRegisterMaps(RegisterMap** _toDwarf,
RegisterMap** _fromDwarf) const = 0;
// returns references
virtual status_t CreateCpuState(CpuState*& _state) = 0;
virtual status_t CreateCpuState(const void* cpuStateData, virtual status_t CreateCpuState(const void* cpuStateData,
size_t size, CpuState*& _state) = 0; size_t size, CpuState*& _state) = 0;
virtual status_t CreateStackFrame(Image* image, virtual status_t CreateStackFrame(Image* image,
@@ -55,6 +63,10 @@ public:
// with the image/function corresponding // with the image/function corresponding
// to the CPU state. // to the CPU state.
virtual status_t ReadValueFromMemory(target_addr_t address,
uint32 valueType, BVariant& _value) const
= 0;
virtual status_t DisassembleCode(FunctionDebugInfo* function, virtual status_t DisassembleCode(FunctionDebugInfo* function,
const void* buffer, size_t bufferSize, const void* buffer, size_t bufferSize,
DisassembledCode*& _sourceCode) = 0; DisassembledCode*& _sourceCode) = 0;
+3 -1
View File
@@ -22,7 +22,9 @@ public:
virtual target_addr_t InstructionPointer() const = 0; virtual target_addr_t InstructionPointer() const = 0;
virtual bool GetRegisterValue(const Register* reg, virtual bool GetRegisterValue(const Register* reg,
BVariant& _value) = 0; BVariant& _value) const = 0;
virtual bool SetRegisterValue(const Register* reg,
const BVariant& value) = 0;
}; };
+31 -6
View File
@@ -3,18 +3,41 @@
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
*/ */
#include "Register.h" #include "Register.h"
#include <TypeConstants.h>
Register::Register(int32 index, const char* name, register_format format,
uint32 bitSize, register_type type) Register::Register(int32 index, const char* name, uint32 bitSize,
uint32 valueType, register_type type, bool calleePreserved)
: :
fIndex(index), fIndex(index),
fName(name), fName(name),
fFormat(format),
fBitSize(bitSize), fBitSize(bitSize),
fType(type) fValueType(valueType),
fType(type),
fCalleePreserved(calleePreserved)
{ {
switch (fValueType) {
case B_INT8_TYPE:
case B_UINT8_TYPE:
case B_INT16_TYPE:
case B_UINT16_TYPE:
case B_INT32_TYPE:
case B_UINT32_TYPE:
case B_INT64_TYPE:
case B_UINT64_TYPE:
fFormat = REGISTER_FORMAT_INTEGER;
break;
case B_FLOAT_TYPE:
case B_DOUBLE_TYPE:
fFormat = REGISTER_FORMAT_FLOAT;
break;
default:
fFormat = 0;
break;
}
} }
@@ -22,8 +45,10 @@ Register::Register(const Register& other)
: :
fIndex(other.fIndex), fIndex(other.fIndex),
fName(other.fName), fName(other.fName),
fFormat(other.fFormat),
fBitSize(other.fBitSize), fBitSize(other.fBitSize),
fType(other.fType) fValueType(other.fValueType),
fFormat(other.fFormat),
fType(other.fType),
fCalleePreserved(other.fCalleePreserved)
{ {
} }
+14 -8
View File
@@ -5,6 +5,7 @@
#ifndef REGISTER_H #ifndef REGISTER_H
#define REGISTER_H #define REGISTER_H
#include <SupportDefs.h> #include <SupportDefs.h>
@@ -25,23 +26,28 @@ enum register_type {
class Register { class Register {
public: public:
Register(int32 index, const char* name, Register(int32 index, const char* name,
register_format format, uint32 bitSize, uint32 bitSize, uint32 valueType,
register_type type); register_type type, bool calleePreserved);
// name will not be cloned // name will not be cloned
Register(const Register& other); Register(const Register& other);
int32 Index() const { return fIndex; } int32 Index() const { return fIndex; }
const char* Name() const { return fName; } const char* Name() const { return fName; }
register_format Format() const { return fFormat; } uint32 ValueType() const { return fValueType; }
uint32 BitSize() const { return fBitSize; } register_format Format() const { return fFormat; }
register_type Type() const { return fType; } uint32 BitSize() const { return fBitSize; }
register_type Type() const { return fType; }
bool IsCalleePreserved() const
{ return fCalleePreserved; }
private: private:
int32 fIndex; int32 fIndex;
const char* fName; const char* fName;
register_format fFormat;
uint32 fBitSize; uint32 fBitSize;
uint32 fValueType;
register_format fFormat;
register_type fType; register_type fType;
bool fCalleePreserved;
}; };
+12
View File
@@ -0,0 +1,12 @@
/*
* Copyright 2009, Ingo Weinhold, [email protected].
* Distributed under the terms of the MIT License.
*/
#include "RegisterMap.h"
RegisterMap::~RegisterMap()
{
}
+21
View File
@@ -0,0 +1,21 @@
/*
* Copyright 2009, Ingo Weinhold, [email protected].
* Distributed under the terms of the MIT License.
*/
#ifndef REGISTER_MAP_H
#define REGISTER_MAP_H
#include <Referenceable.h>
class RegisterMap : public Referenceable {
public:
virtual ~RegisterMap();
virtual int32 CountRegisters() const = 0;
virtual int32 MapRegisterIndex(int32 index) const = 0;
};
#endif // REGISTER_MAP_H
+215 -35
View File
@@ -3,6 +3,7 @@
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
*/ */
#include "ArchitectureX86.h" #include "ArchitectureX86.h"
#include <new> #include <new>
@@ -15,6 +16,7 @@
#include "DisassembledCode.h" #include "DisassembledCode.h"
#include "FunctionDebugInfo.h" #include "FunctionDebugInfo.h"
#include "InstructionInfo.h" #include "InstructionInfo.h"
#include "RegisterMap.h"
#include "StackFrame.h" #include "StackFrame.h"
#include "Statement.h" #include "Statement.h"
#include "TeamMemory.h" #include "TeamMemory.h"
@@ -22,15 +24,98 @@
#include "disasm/DisassemblerX86.h" #include "disasm/DisassemblerX86.h"
static const int32 kFromDwarfRegisters[] = {
X86_REGISTER_EAX,
X86_REGISTER_ECX,
X86_REGISTER_EDX,
X86_REGISTER_EBX,
X86_REGISTER_ESP,
X86_REGISTER_EBP,
X86_REGISTER_ESI,
X86_REGISTER_EDI,
X86_REGISTER_EIP,
-1, // eflags
-1, // trap number
-1, // st(0)
-1, // st(1)
-1, // st(2)
-1, // st(3)
-1, // st(4)
-1, // st(5)
-1, // st(6)
-1, // st(7)
-1, // ?
-1, // ?
-1, -1, -1, -1, -1, -1, -1, -1, // SSE
-1, -1, -1, -1, -1, -1, -1, -1 // MMX
};
static const int32 kFromDwarfRegisterCount = sizeof(kFromDwarfRegisters) / 4;
// #pragma mark - ToDwarfRegisterMap
struct ArchitectureX86::ToDwarfRegisterMap : RegisterMap {
ToDwarfRegisterMap()
{
// init the index array from the reverse map
memset(fIndices, -1, sizeof(fIndices));
for (int32 i = 0; i < kFromDwarfRegisterCount; i++) {
if (kFromDwarfRegisters[i] >= 0)
fIndices[kFromDwarfRegisters[i]] = i;
}
}
virtual int32 CountRegisters() const
{
return X86_REGISTER_COUNT;
}
virtual int32 MapRegisterIndex(int32 index) const
{
return index >= 0 && index < X86_REGISTER_COUNT ? fIndices[index] : -1;
}
private:
int32 fIndices[X86_REGISTER_COUNT];
};
// #pragma mark - FromDwarfRegisterMap
struct ArchitectureX86::FromDwarfRegisterMap : RegisterMap {
virtual int32 CountRegisters() const
{
return kFromDwarfRegisterCount;
}
virtual int32 MapRegisterIndex(int32 index) const
{
return index >= 0 && index < kFromDwarfRegisterCount
? kFromDwarfRegisters[index] : -1;
}
};
// #pragma mark - ArchitectureX86
ArchitectureX86::ArchitectureX86(TeamMemory* teamMemory) ArchitectureX86::ArchitectureX86(TeamMemory* teamMemory)
: :
Architecture(teamMemory) Architecture(teamMemory),
fToDwarfRegisterMap(NULL),
fFromDwarfRegisterMap(NULL)
{ {
} }
ArchitectureX86::~ArchitectureX86() ArchitectureX86::~ArchitectureX86()
{ {
if (fToDwarfRegisterMap != NULL)
fToDwarfRegisterMap->ReleaseReference();
if (fFromDwarfRegisterMap != NULL)
fFromDwarfRegisterMap->ReleaseReference();
} }
@@ -38,43 +123,49 @@ status_t
ArchitectureX86::Init() ArchitectureX86::Init()
{ {
try { try {
_AddIntegerRegister(X86_REGISTER_EIP, "eip", 32, _AddIntegerRegister(X86_REGISTER_EIP, "eip", B_UINT32_TYPE,
REGISTER_TYPE_INSTRUCTION_POINTER); REGISTER_TYPE_INSTRUCTION_POINTER, false);
_AddIntegerRegister(X86_REGISTER_ESP, "esp", 32, _AddIntegerRegister(X86_REGISTER_ESP, "esp", B_UINT32_TYPE,
REGISTER_TYPE_STACK_POINTER); REGISTER_TYPE_STACK_POINTER, true);
_AddIntegerRegister(X86_REGISTER_EBP, "ebp", 32, _AddIntegerRegister(X86_REGISTER_EBP, "ebp", B_UINT32_TYPE,
REGISTER_TYPE_GENERAL_PURPOSE); REGISTER_TYPE_GENERAL_PURPOSE, true);
_AddIntegerRegister(X86_REGISTER_EAX, "eax", 32, _AddIntegerRegister(X86_REGISTER_EAX, "eax", B_UINT32_TYPE,
REGISTER_TYPE_GENERAL_PURPOSE); REGISTER_TYPE_GENERAL_PURPOSE, false);
_AddIntegerRegister(X86_REGISTER_EBX, "ebx", 32, _AddIntegerRegister(X86_REGISTER_EBX, "ebx", B_UINT32_TYPE,
REGISTER_TYPE_GENERAL_PURPOSE); REGISTER_TYPE_GENERAL_PURPOSE, true);
_AddIntegerRegister(X86_REGISTER_ECX, "ecx", 32, _AddIntegerRegister(X86_REGISTER_ECX, "ecx", B_UINT32_TYPE,
REGISTER_TYPE_GENERAL_PURPOSE); REGISTER_TYPE_GENERAL_PURPOSE, false);
_AddIntegerRegister(X86_REGISTER_EDX, "edx", 32, _AddIntegerRegister(X86_REGISTER_EDX, "edx", B_UINT32_TYPE,
REGISTER_TYPE_GENERAL_PURPOSE); REGISTER_TYPE_GENERAL_PURPOSE, false);
_AddIntegerRegister(X86_REGISTER_ESI, "esi", 32, _AddIntegerRegister(X86_REGISTER_ESI, "esi", B_UINT32_TYPE,
REGISTER_TYPE_GENERAL_PURPOSE); REGISTER_TYPE_GENERAL_PURPOSE, true);
_AddIntegerRegister(X86_REGISTER_EDI, "edi", 32, _AddIntegerRegister(X86_REGISTER_EDI, "edi", B_UINT32_TYPE,
REGISTER_TYPE_GENERAL_PURPOSE); REGISTER_TYPE_GENERAL_PURPOSE, true);
_AddIntegerRegister(X86_REGISTER_CS, "cs", 16, _AddIntegerRegister(X86_REGISTER_CS, "cs", B_UINT16_TYPE,
REGISTER_TYPE_SPECIAL_PURPOSE); REGISTER_TYPE_SPECIAL_PURPOSE, true);
_AddIntegerRegister(X86_REGISTER_DS, "ds", 16, _AddIntegerRegister(X86_REGISTER_DS, "ds", B_UINT16_TYPE,
REGISTER_TYPE_SPECIAL_PURPOSE); REGISTER_TYPE_SPECIAL_PURPOSE, true);
_AddIntegerRegister(X86_REGISTER_ES, "es", 16, _AddIntegerRegister(X86_REGISTER_ES, "es", B_UINT16_TYPE,
REGISTER_TYPE_SPECIAL_PURPOSE); REGISTER_TYPE_SPECIAL_PURPOSE, true);
_AddIntegerRegister(X86_REGISTER_FS, "fs", 16, _AddIntegerRegister(X86_REGISTER_FS, "fs", B_UINT16_TYPE,
REGISTER_TYPE_SPECIAL_PURPOSE); REGISTER_TYPE_SPECIAL_PURPOSE, true);
_AddIntegerRegister(X86_REGISTER_GS, "gs", 16, _AddIntegerRegister(X86_REGISTER_GS, "gs", B_UINT16_TYPE,
REGISTER_TYPE_SPECIAL_PURPOSE); REGISTER_TYPE_SPECIAL_PURPOSE, true);
_AddIntegerRegister(X86_REGISTER_SS, "ss", 16, _AddIntegerRegister(X86_REGISTER_SS, "ss", B_UINT16_TYPE,
REGISTER_TYPE_SPECIAL_PURPOSE); REGISTER_TYPE_SPECIAL_PURPOSE, true);
} catch (std::bad_alloc) { } catch (std::bad_alloc) {
return B_NO_MEMORY; return B_NO_MEMORY;
} }
fToDwarfRegisterMap = new(std::nothrow) ToDwarfRegisterMap;
fFromDwarfRegisterMap = new(std::nothrow) FromDwarfRegisterMap;
if (fToDwarfRegisterMap == NULL || fFromDwarfRegisterMap == NULL)
return B_NO_MEMORY;
return B_OK; return B_OK;
} }
@@ -93,6 +184,36 @@ ArchitectureX86::Registers() const
} }
status_t
ArchitectureX86::GetDwarfRegisterMaps(RegisterMap** _toDwarf,
RegisterMap** _fromDwarf) const
{
if (_toDwarf != NULL) {
*_toDwarf = fToDwarfRegisterMap;
fToDwarfRegisterMap->AcquireReference();
}
if (_fromDwarf != NULL) {
*_fromDwarf = fFromDwarfRegisterMap;
fFromDwarfRegisterMap->AcquireReference();
}
return B_OK;
}
status_t
ArchitectureX86::CreateCpuState(CpuState*& _state)
{
CpuStateX86* state = new(std::nothrow) CpuStateX86;
if (state == NULL)
return B_NO_MEMORY;
_state = state;
return B_OK;
}
status_t status_t
ArchitectureX86::CreateCpuState(const void* cpuStateData, size_t size, ArchitectureX86::CreateCpuState(const void* cpuStateData, size_t size,
CpuState*& _state) CpuState*& _state)
@@ -269,6 +390,62 @@ ArchitectureX86::UpdateStackFrameCpuState(const StackFrame* frame,
} }
status_t
ArchitectureX86::ReadValueFromMemory(target_addr_t address, uint32 valueType,
BVariant& _value) const
{
uint8 buffer[64];
size_t size = BVariant::SizeOfType(valueType);
if (size == 0 || size > sizeof(buffer))
return B_BAD_VALUE;
ssize_t bytesRead = fTeamMemory->ReadMemory(address, buffer, size);
if (bytesRead < 0)
return bytesRead;
if ((size_t)bytesRead != size)
return B_ERROR;
// TODO: We need to swap endianess, if the host is big endian!
switch (valueType) {
case B_INT8_TYPE:
_value.SetTo(*(int8*)buffer);
return B_OK;
case B_UINT8_TYPE:
_value.SetTo(*(uint8*)buffer);
return B_OK;
case B_INT16_TYPE:
_value.SetTo(*(int16*)buffer);
return B_OK;
case B_UINT16_TYPE:
_value.SetTo(*(uint16*)buffer);
return B_OK;
case B_INT32_TYPE:
_value.SetTo(*(int32*)buffer);
return B_OK;
case B_UINT32_TYPE:
_value.SetTo(*(uint32*)buffer);
return B_OK;
case B_INT64_TYPE:
_value.SetTo(*(int64*)buffer);
return B_OK;
case B_UINT64_TYPE:
_value.SetTo(*(uint64*)buffer);
return B_OK;
case B_FLOAT_TYPE:
_value.SetTo(*(float*)buffer);
// TODO: float on the host might work differently!
return B_OK;
case B_DOUBLE_TYPE:
_value.SetTo(*(double*)buffer);
// TODO: double on the host might work differently!
return B_OK;
default:
return B_BAD_VALUE;
}
}
status_t status_t
ArchitectureX86::DisassembleCode(FunctionDebugInfo* function, ArchitectureX86::DisassembleCode(FunctionDebugInfo* function,
const void* buffer, size_t bufferSize, DisassembledCode*& _sourceCode) const void* buffer, size_t bufferSize, DisassembledCode*& _sourceCode)
@@ -382,18 +559,21 @@ ArchitectureX86::GetInstructionInfo(target_addr_t address,
void void
ArchitectureX86::_AddRegister(int32 index, const char* name, ArchitectureX86::_AddRegister(int32 index, const char* name,
register_format format, uint32 bitSize, register_type type) uint32 bitSize, uint32 valueType, register_type type, bool calleePreserved)
{ {
if (!fRegisters.Add(Register(index, name, format, bitSize, type))) if (!fRegisters.Add(Register(index, name, bitSize, valueType, type,
calleePreserved))) {
throw std::bad_alloc(); throw std::bad_alloc();
}
} }
void void
ArchitectureX86::_AddIntegerRegister(int32 index, const char* name, ArchitectureX86::_AddIntegerRegister(int32 index, const char* name,
uint32 bitSize, register_type type) uint32 valueType, register_type type, bool calleePreserved)
{ {
_AddRegister(index, name, REGISTER_FORMAT_INTEGER, bitSize, type); _AddRegister(index, name, 8 * BVariant::SizeOfType(valueType), valueType,
type, calleePreserved);
} }
+18 -4
View File
@@ -5,6 +5,7 @@
#ifndef ARCHITECTURE_X86_H #ifndef ARCHITECTURE_X86_H
#define ARCHITECTURE_X86_H #define ARCHITECTURE_X86_H
#include "Architecture.h" #include "Architecture.h"
#include "Array.h" #include "Array.h"
#include "Register.h" #include "Register.h"
@@ -20,6 +21,10 @@ public:
virtual int32 CountRegisters() const; virtual int32 CountRegisters() const;
virtual const Register* Registers() const; virtual const Register* Registers() const;
virtual status_t GetDwarfRegisterMaps(RegisterMap** _toDwarf,
RegisterMap** _fromDwarf) const;
virtual status_t CreateCpuState(CpuState*& _state);
virtual status_t CreateCpuState(const void* cpuStateData, virtual status_t CreateCpuState(const void* cpuStateData,
size_t size, CpuState*& _state); size_t size, CpuState*& _state);
virtual status_t CreateStackFrame(Image* image, virtual status_t CreateStackFrame(Image* image,
@@ -33,6 +38,9 @@ public:
FunctionDebugInfo* previousFunction, FunctionDebugInfo* previousFunction,
CpuState* previousCpuState); CpuState* previousCpuState);
virtual status_t ReadValueFromMemory(target_addr_t address,
uint32 valueType, BVariant& _value) const;
virtual status_t DisassembleCode(FunctionDebugInfo* function, virtual status_t DisassembleCode(FunctionDebugInfo* function,
const void* buffer, size_t bufferSize, const void* buffer, size_t bufferSize,
DisassembledCode*& _sourceCode); DisassembledCode*& _sourceCode);
@@ -42,19 +50,25 @@ public:
virtual status_t GetInstructionInfo(target_addr_t address, virtual status_t GetInstructionInfo(target_addr_t address,
InstructionInfo& _info); InstructionInfo& _info);
private:
struct ToDwarfRegisterMap;
struct FromDwarfRegisterMap;
private: private:
void _AddRegister(int32 index, const char* name, void _AddRegister(int32 index, const char* name,
register_format format, uint32 bitSize, uint32 bitSize, uint32 valueType,
register_type type); register_type type, bool calleePreserved);
void _AddIntegerRegister(int32 index, void _AddIntegerRegister(int32 index,
const char* name, uint32 bitSize, const char* name, uint32 valueType,
register_type type); register_type type, bool calleePreserved);
bool _HasFunctionPrologue( bool _HasFunctionPrologue(
FunctionDebugInfo* function) const; FunctionDebugInfo* function) const;
private: private:
Array<Register> fRegisters; Array<Register> fRegisters;
ToDwarfRegisterMap* fToDwarfRegisterMap;
FromDwarfRegisterMap* fFromDwarfRegisterMap;
}; };
+14 -1
View File
@@ -55,7 +55,7 @@ CpuStateX86::InstructionPointer() const
bool bool
CpuStateX86::GetRegisterValue(const Register* reg, BVariant& _value) CpuStateX86::GetRegisterValue(const Register* reg, BVariant& _value) const
{ {
int32 index = reg->Index(); int32 index = reg->Index();
if (!IsRegisterSet(index)) if (!IsRegisterSet(index))
@@ -73,6 +73,19 @@ CpuStateX86::GetRegisterValue(const Register* reg, BVariant& _value)
} }
bool
CpuStateX86::SetRegisterValue(const Register* reg, const BVariant& value)
{
int32 index = reg->Index();
if (index >= X86_INT_REGISTER_END)
return false;
fIntRegisters[index] = value.ToUInt32();
fSetRegisters[index] = 1;
return true;
}
bool bool
CpuStateX86::IsRegisterSet(int32 index) const CpuStateX86::IsRegisterSet(int32 index) const
{ {
+3 -1
View File
@@ -48,7 +48,9 @@ public:
virtual target_addr_t InstructionPointer() const; virtual target_addr_t InstructionPointer() const;
virtual bool GetRegisterValue(const Register* reg, virtual bool GetRegisterValue(const Register* reg,
BVariant& _value); BVariant& _value) const;
virtual bool SetRegisterValue(const Register* reg,
const BVariant& value);
uint32 InterruptVector() const uint32 InterruptVector() const
{ return fInterruptVector; } { return fInterruptVector; }