* 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:
@@ -44,6 +44,7 @@ Application Debugger :
|
||||
CpuState.cpp
|
||||
InstructionInfo.cpp
|
||||
Register.cpp
|
||||
RegisterMap.cpp
|
||||
|
||||
# arch/x86
|
||||
ArchitectureX86.cpp
|
||||
|
||||
@@ -52,7 +52,6 @@ Architecture::CreateStackTrace(Team* team,
|
||||
return B_NO_MEMORY;
|
||||
ObjectDeleter<StackTrace> stackTraceDeleter(stackTrace);
|
||||
|
||||
bool architectureFrame = false;
|
||||
StackFrame* frame = NULL;
|
||||
|
||||
while (cpuState != NULL) {
|
||||
@@ -85,9 +84,10 @@ Architecture::CreateStackTrace(Team* team,
|
||||
Reference<FunctionInstance> 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);
|
||||
|
||||
|
||||
@@ -5,9 +5,11 @@
|
||||
#ifndef ARCHITECTURE_H
|
||||
#define ARCHITECTURE_H
|
||||
|
||||
|
||||
#include <OS.h>
|
||||
|
||||
#include <Referenceable.h>
|
||||
#include <Variant.h>
|
||||
|
||||
#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;
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -3,18 +3,41 @@
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
|
||||
#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),
|
||||
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)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#ifndef REGISTER_H
|
||||
#define REGISTER_H
|
||||
|
||||
|
||||
#include <SupportDefs.h>
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
/*
|
||||
* Copyright 2009, Ingo Weinhold, [email protected].
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
|
||||
#include "RegisterMap.h"
|
||||
|
||||
|
||||
RegisterMap::~RegisterMap()
|
||||
{
|
||||
}
|
||||
@@ -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
|
||||
@@ -3,6 +3,7 @@
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
|
||||
#include "ArchitectureX86.h"
|
||||
|
||||
#include <new>
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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<Register> fRegisters;
|
||||
ToDwarfRegisterMap* fToDwarfRegisterMap;
|
||||
FromDwarfRegisterMap* fFromDwarfRegisterMap;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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; }
|
||||
|
||||
Reference in New Issue
Block a user