From 614e1dc42fb2c04ff44bda621bea500d01d6a4c3 Mon Sep 17 00:00:00 2001 From: Ingo Weinhold Date: Mon, 13 Jul 2009 18:45:49 +0000 Subject: [PATCH] * 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 --- src/apps/debugger/Jamfile | 1 + src/apps/debugger/arch/Architecture.cpp | 12 +- src/apps/debugger/arch/Architecture.h | 12 + src/apps/debugger/arch/CpuState.h | 4 +- src/apps/debugger/arch/Register.cpp | 37 ++- src/apps/debugger/arch/Register.h | 22 +- src/apps/debugger/arch/RegisterMap.cpp | 12 + src/apps/debugger/arch/RegisterMap.h | 21 ++ .../debugger/arch/x86/ArchitectureX86.cpp | 250 +++++++++++++++--- src/apps/debugger/arch/x86/ArchitectureX86.h | 22 +- src/apps/debugger/arch/x86/CpuStateX86.cpp | 15 +- src/apps/debugger/arch/x86/CpuStateX86.h | 4 +- 12 files changed, 349 insertions(+), 63 deletions(-) create mode 100644 src/apps/debugger/arch/RegisterMap.cpp create mode 100644 src/apps/debugger/arch/RegisterMap.h diff --git a/src/apps/debugger/Jamfile b/src/apps/debugger/Jamfile index 59432d2776..082cfd0922 100644 --- a/src/apps/debugger/Jamfile +++ b/src/apps/debugger/Jamfile @@ -44,6 +44,7 @@ Application Debugger : CpuState.cpp InstructionInfo.cpp Register.cpp + RegisterMap.cpp # arch/x86 ArchitectureX86.cpp diff --git a/src/apps/debugger/arch/Architecture.cpp b/src/apps/debugger/arch/Architecture.cpp index b0eaf2e025..92c00ede8f 100644 --- a/src/apps/debugger/arch/Architecture.cpp +++ b/src/apps/debugger/arch/Architecture.cpp @@ -52,7 +52,6 @@ Architecture::CreateStackTrace(Team* team, return B_NO_MEMORY; ObjectDeleter stackTraceDeleter(stackTrace); - bool architectureFrame = false; StackFrame* frame = NULL; while (cpuState != NULL) { @@ -85,9 +84,10 @@ Architecture::CreateStackTrace(Team* team, Reference functionReference(function); teamLocker.Unlock(); - // If the last frame had been created by the architecture, we update the - // CPU state. - if (architectureFrame) { + // If the CPU state's instruction pointer is actually the return address + // of the next frame, we let the architecture fix that. + if (frame != NULL + && frame->ReturnAddress() == cpuState->InstructionPointer()) { UpdateStackFrameCpuState(frame, image, functionDebugInfo, cpuState); } @@ -109,9 +109,7 @@ Architecture::CreateStackTrace(Team* team, cpuState, frame == NULL, previousFrame, previousCpuState); if (error != B_OK) break; - architectureFrame = true; - } else - architectureFrame = false; + } cpuStateReference.SetTo(previousCpuState, true); diff --git a/src/apps/debugger/arch/Architecture.h b/src/apps/debugger/arch/Architecture.h index 6cf2167ee2..6d0170c353 100644 --- a/src/apps/debugger/arch/Architecture.h +++ b/src/apps/debugger/arch/Architecture.h @@ -5,9 +5,11 @@ #ifndef ARCHITECTURE_H #define ARCHITECTURE_H + #include #include +#include #include "Types.h" @@ -19,6 +21,7 @@ class Image; class ImageDebugInfoProvider; class InstructionInfo; class Register; +class RegisterMap; class StackFrame; class StackTrace; class Statement; @@ -36,6 +39,11 @@ public: virtual int32 CountRegisters() 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, size_t size, CpuState*& _state) = 0; virtual status_t CreateStackFrame(Image* image, @@ -55,6 +63,10 @@ public: // with the image/function corresponding // to the CPU state. + virtual status_t ReadValueFromMemory(target_addr_t address, + uint32 valueType, BVariant& _value) const + = 0; + virtual status_t DisassembleCode(FunctionDebugInfo* function, const void* buffer, size_t bufferSize, DisassembledCode*& _sourceCode) = 0; diff --git a/src/apps/debugger/arch/CpuState.h b/src/apps/debugger/arch/CpuState.h index 7f53d27fb9..4091b22ff3 100644 --- a/src/apps/debugger/arch/CpuState.h +++ b/src/apps/debugger/arch/CpuState.h @@ -22,7 +22,9 @@ public: virtual target_addr_t InstructionPointer() const = 0; virtual bool GetRegisterValue(const Register* reg, - BVariant& _value) = 0; + BVariant& _value) const = 0; + virtual bool SetRegisterValue(const Register* reg, + const BVariant& value) = 0; }; diff --git a/src/apps/debugger/arch/Register.cpp b/src/apps/debugger/arch/Register.cpp index 2f8449c566..af7d13cb2a 100644 --- a/src/apps/debugger/arch/Register.cpp +++ b/src/apps/debugger/arch/Register.cpp @@ -3,18 +3,41 @@ * Distributed under the terms of the MIT License. */ + #include "Register.h" +#include -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), fName(name), - fFormat(format), 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), fName(other.fName), - fFormat(other.fFormat), fBitSize(other.fBitSize), - fType(other.fType) + fValueType(other.fValueType), + fFormat(other.fFormat), + fType(other.fType), + fCalleePreserved(other.fCalleePreserved) { } diff --git a/src/apps/debugger/arch/Register.h b/src/apps/debugger/arch/Register.h index e69e700780..06ef5eb92a 100644 --- a/src/apps/debugger/arch/Register.h +++ b/src/apps/debugger/arch/Register.h @@ -5,6 +5,7 @@ #ifndef REGISTER_H #define REGISTER_H + #include @@ -25,23 +26,28 @@ enum register_type { class Register { public: Register(int32 index, const char* name, - register_format format, uint32 bitSize, - register_type type); + uint32 bitSize, uint32 valueType, + register_type type, bool calleePreserved); // 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; } + int32 Index() const { return fIndex; } + const char* Name() const { return fName; } + uint32 ValueType() const { return fValueType; } + register_format Format() const { return fFormat; } + uint32 BitSize() const { return fBitSize; } + register_type Type() const { return fType; } + bool IsCalleePreserved() const + { return fCalleePreserved; } private: int32 fIndex; const char* fName; - register_format fFormat; uint32 fBitSize; + uint32 fValueType; + register_format fFormat; register_type fType; + bool fCalleePreserved; }; diff --git a/src/apps/debugger/arch/RegisterMap.cpp b/src/apps/debugger/arch/RegisterMap.cpp new file mode 100644 index 0000000000..c0afc2a068 --- /dev/null +++ b/src/apps/debugger/arch/RegisterMap.cpp @@ -0,0 +1,12 @@ +/* + * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. + * Distributed under the terms of the MIT License. + */ + + +#include "RegisterMap.h" + + +RegisterMap::~RegisterMap() +{ +} diff --git a/src/apps/debugger/arch/RegisterMap.h b/src/apps/debugger/arch/RegisterMap.h new file mode 100644 index 0000000000..81611a898e --- /dev/null +++ b/src/apps/debugger/arch/RegisterMap.h @@ -0,0 +1,21 @@ +/* + * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. + * Distributed under the terms of the MIT License. + */ +#ifndef REGISTER_MAP_H +#define REGISTER_MAP_H + + +#include + + +class RegisterMap : public Referenceable { +public: + virtual ~RegisterMap(); + + virtual int32 CountRegisters() const = 0; + virtual int32 MapRegisterIndex(int32 index) const = 0; +}; + + +#endif // REGISTER_MAP_H diff --git a/src/apps/debugger/arch/x86/ArchitectureX86.cpp b/src/apps/debugger/arch/x86/ArchitectureX86.cpp index 8b93119636..6785a4ad29 100644 --- a/src/apps/debugger/arch/x86/ArchitectureX86.cpp +++ b/src/apps/debugger/arch/x86/ArchitectureX86.cpp @@ -3,6 +3,7 @@ * Distributed under the terms of the MIT License. */ + #include "ArchitectureX86.h" #include @@ -15,6 +16,7 @@ #include "DisassembledCode.h" #include "FunctionDebugInfo.h" #include "InstructionInfo.h" +#include "RegisterMap.h" #include "StackFrame.h" #include "Statement.h" #include "TeamMemory.h" @@ -22,15 +24,98 @@ #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) : - Architecture(teamMemory) + Architecture(teamMemory), + fToDwarfRegisterMap(NULL), + fFromDwarfRegisterMap(NULL) { } ArchitectureX86::~ArchitectureX86() { + if (fToDwarfRegisterMap != NULL) + fToDwarfRegisterMap->ReleaseReference(); + if (fFromDwarfRegisterMap != NULL) + fFromDwarfRegisterMap->ReleaseReference(); } @@ -38,43 +123,49 @@ status_t ArchitectureX86::Init() { try { - _AddIntegerRegister(X86_REGISTER_EIP, "eip", 32, - REGISTER_TYPE_INSTRUCTION_POINTER); - _AddIntegerRegister(X86_REGISTER_ESP, "esp", 32, - REGISTER_TYPE_STACK_POINTER); - _AddIntegerRegister(X86_REGISTER_EBP, "ebp", 32, - REGISTER_TYPE_GENERAL_PURPOSE); + _AddIntegerRegister(X86_REGISTER_EIP, "eip", B_UINT32_TYPE, + REGISTER_TYPE_INSTRUCTION_POINTER, false); + _AddIntegerRegister(X86_REGISTER_ESP, "esp", B_UINT32_TYPE, + REGISTER_TYPE_STACK_POINTER, true); + _AddIntegerRegister(X86_REGISTER_EBP, "ebp", B_UINT32_TYPE, + REGISTER_TYPE_GENERAL_PURPOSE, true); - _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_EAX, "eax", B_UINT32_TYPE, + REGISTER_TYPE_GENERAL_PURPOSE, false); + _AddIntegerRegister(X86_REGISTER_EBX, "ebx", B_UINT32_TYPE, + REGISTER_TYPE_GENERAL_PURPOSE, true); + _AddIntegerRegister(X86_REGISTER_ECX, "ecx", B_UINT32_TYPE, + REGISTER_TYPE_GENERAL_PURPOSE, false); + _AddIntegerRegister(X86_REGISTER_EDX, "edx", B_UINT32_TYPE, + REGISTER_TYPE_GENERAL_PURPOSE, false); - _AddIntegerRegister(X86_REGISTER_ESI, "esi", 32, - REGISTER_TYPE_GENERAL_PURPOSE); - _AddIntegerRegister(X86_REGISTER_EDI, "edi", 32, - REGISTER_TYPE_GENERAL_PURPOSE); + _AddIntegerRegister(X86_REGISTER_ESI, "esi", B_UINT32_TYPE, + REGISTER_TYPE_GENERAL_PURPOSE, true); + _AddIntegerRegister(X86_REGISTER_EDI, "edi", B_UINT32_TYPE, + REGISTER_TYPE_GENERAL_PURPOSE, true); - _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); + _AddIntegerRegister(X86_REGISTER_CS, "cs", B_UINT16_TYPE, + REGISTER_TYPE_SPECIAL_PURPOSE, true); + _AddIntegerRegister(X86_REGISTER_DS, "ds", B_UINT16_TYPE, + REGISTER_TYPE_SPECIAL_PURPOSE, true); + _AddIntegerRegister(X86_REGISTER_ES, "es", B_UINT16_TYPE, + REGISTER_TYPE_SPECIAL_PURPOSE, true); + _AddIntegerRegister(X86_REGISTER_FS, "fs", B_UINT16_TYPE, + REGISTER_TYPE_SPECIAL_PURPOSE, true); + _AddIntegerRegister(X86_REGISTER_GS, "gs", B_UINT16_TYPE, + REGISTER_TYPE_SPECIAL_PURPOSE, true); + _AddIntegerRegister(X86_REGISTER_SS, "ss", B_UINT16_TYPE, + REGISTER_TYPE_SPECIAL_PURPOSE, true); } catch (std::bad_alloc) { 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; } @@ -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 ArchitectureX86::CreateCpuState(const void* cpuStateData, size_t size, 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 ArchitectureX86::DisassembleCode(FunctionDebugInfo* function, const void* buffer, size_t bufferSize, DisassembledCode*& _sourceCode) @@ -382,18 +559,21 @@ ArchitectureX86::GetInstructionInfo(target_addr_t address, void 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(); + } } void 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); } diff --git a/src/apps/debugger/arch/x86/ArchitectureX86.h b/src/apps/debugger/arch/x86/ArchitectureX86.h index 3b31e8240f..f55c8da486 100644 --- a/src/apps/debugger/arch/x86/ArchitectureX86.h +++ b/src/apps/debugger/arch/x86/ArchitectureX86.h @@ -5,6 +5,7 @@ #ifndef ARCHITECTURE_X86_H #define ARCHITECTURE_X86_H + #include "Architecture.h" #include "Array.h" #include "Register.h" @@ -20,6 +21,10 @@ public: virtual int32 CountRegisters() 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, size_t size, CpuState*& _state); virtual status_t CreateStackFrame(Image* image, @@ -33,6 +38,9 @@ public: FunctionDebugInfo* previousFunction, CpuState* previousCpuState); + virtual status_t ReadValueFromMemory(target_addr_t address, + uint32 valueType, BVariant& _value) const; + virtual status_t DisassembleCode(FunctionDebugInfo* function, const void* buffer, size_t bufferSize, DisassembledCode*& _sourceCode); @@ -42,19 +50,25 @@ public: virtual status_t GetInstructionInfo(target_addr_t address, InstructionInfo& _info); +private: + struct ToDwarfRegisterMap; + struct FromDwarfRegisterMap; + private: void _AddRegister(int32 index, const char* name, - register_format format, uint32 bitSize, - register_type type); + uint32 bitSize, uint32 valueType, + register_type type, bool calleePreserved); void _AddIntegerRegister(int32 index, - const char* name, uint32 bitSize, - register_type type); + const char* name, uint32 valueType, + register_type type, bool calleePreserved); bool _HasFunctionPrologue( FunctionDebugInfo* function) const; private: Array fRegisters; + ToDwarfRegisterMap* fToDwarfRegisterMap; + FromDwarfRegisterMap* fFromDwarfRegisterMap; }; diff --git a/src/apps/debugger/arch/x86/CpuStateX86.cpp b/src/apps/debugger/arch/x86/CpuStateX86.cpp index a047bf1184..c0660be2df 100644 --- a/src/apps/debugger/arch/x86/CpuStateX86.cpp +++ b/src/apps/debugger/arch/x86/CpuStateX86.cpp @@ -55,7 +55,7 @@ CpuStateX86::InstructionPointer() const bool -CpuStateX86::GetRegisterValue(const Register* reg, BVariant& _value) +CpuStateX86::GetRegisterValue(const Register* reg, BVariant& _value) const { int32 index = reg->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 CpuStateX86::IsRegisterSet(int32 index) const { diff --git a/src/apps/debugger/arch/x86/CpuStateX86.h b/src/apps/debugger/arch/x86/CpuStateX86.h index 9fdab15109..d6befe95f8 100644 --- a/src/apps/debugger/arch/x86/CpuStateX86.h +++ b/src/apps/debugger/arch/x86/CpuStateX86.h @@ -48,7 +48,9 @@ public: virtual target_addr_t InstructionPointer() const; virtual bool GetRegisterValue(const Register* reg, - BVariant& _value); + BVariant& _value) const; + virtual bool SetRegisterValue(const Register* reg, + const BVariant& value); uint32 InterruptVector() const { return fInterruptVector; }