* Moved the outer dependencies for the expression evaluation into new class
DwarfExpressionEvaluationContext. * Implemented the remaining operations save DW_OP_piece and DW_OP_bit_piece. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@31590 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
137ded7516
commit
dec24704e1
|
@ -30,6 +30,23 @@ static const size_t kMaxStackCapacity = 1024;
|
||||||
static const uint32 kMaxOperationCount = 10000;
|
static const uint32 kMaxOperationCount = 10000;
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark - DwarfExpressionEvaluationContext
|
||||||
|
|
||||||
|
|
||||||
|
DwarfExpressionEvaluationContext::DwarfExpressionEvaluationContext(
|
||||||
|
DwarfTargetInterface* targetInterface, uint8 addressSize)
|
||||||
|
:
|
||||||
|
fTargetInterface(targetInterface),
|
||||||
|
fAddressSize(addressSize)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
DwarfExpressionEvaluationContext::~DwarfExpressionEvaluationContext()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// #pragma mark - EvaluationException
|
// #pragma mark - EvaluationException
|
||||||
|
|
||||||
|
|
||||||
|
@ -79,17 +96,12 @@ DwarfExpressionEvaluator::_Pop()
|
||||||
|
|
||||||
|
|
||||||
DwarfExpressionEvaluator::DwarfExpressionEvaluator(
|
DwarfExpressionEvaluator::DwarfExpressionEvaluator(
|
||||||
DwarfTargetInterface* targetInterface, uint8 addressSize)
|
DwarfExpressionEvaluationContext* context)
|
||||||
:
|
:
|
||||||
fTargetInterface(targetInterface),
|
fContext(context),
|
||||||
fStack(NULL),
|
fStack(NULL),
|
||||||
fStackSize(0),
|
fStackSize(0),
|
||||||
fStackCapacity(0),
|
fStackCapacity(0)
|
||||||
fObjectAddress(0),
|
|
||||||
fFrameAddress(0),
|
|
||||||
fAddressSize(addressSize),
|
|
||||||
fObjectAddressValid(false),
|
|
||||||
fFrameAddressValid(false)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -100,26 +112,10 @@ DwarfExpressionEvaluator::~DwarfExpressionEvaluator()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
DwarfExpressionEvaluator::SetObjectAddress(target_addr_t address)
|
|
||||||
{
|
|
||||||
fObjectAddress = address;
|
|
||||||
fObjectAddressValid = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
DwarfExpressionEvaluator::SetFrameAddress(target_addr_t address)
|
|
||||||
{
|
|
||||||
fFrameAddress = address;
|
|
||||||
fFrameAddressValid = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
DwarfExpressionEvaluator::Evaluate(const void* expression, size_t size)
|
DwarfExpressionEvaluator::Evaluate(const void* expression, size_t size)
|
||||||
{
|
{
|
||||||
fDataReader.SetTo(expression, size, fAddressSize);
|
fDataReader.SetTo(expression, size, fContext->AddressSize());
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return _Evaluate();
|
return _Evaluate();
|
||||||
|
@ -208,13 +204,13 @@ DwarfExpressionEvaluator::_Evaluate()
|
||||||
}
|
}
|
||||||
|
|
||||||
case DW_OP_deref:
|
case DW_OP_deref:
|
||||||
_DereferenceAddress(fAddressSize);
|
_DereferenceAddress(fContext->AddressSize());
|
||||||
break;
|
break;
|
||||||
case DW_OP_deref_size:
|
case DW_OP_deref_size:
|
||||||
_DereferenceAddress(fDataReader.Read<uint8>(0));
|
_DereferenceAddress(fDataReader.Read<uint8>(0));
|
||||||
break;
|
break;
|
||||||
case DW_OP_xderef:
|
case DW_OP_xderef:
|
||||||
_DereferenceAddressSpaceAddress(fAddressSize);
|
_DereferenceAddressSpaceAddress(fContext->AddressSize());
|
||||||
break;
|
break;
|
||||||
case DW_OP_xderef_size:
|
case DW_OP_xderef_size:
|
||||||
_DereferenceAddressSpaceAddress(fDataReader.Read<uint8>(0));
|
_DereferenceAddressSpaceAddress(fDataReader.Read<uint8>(0));
|
||||||
|
@ -223,7 +219,7 @@ DwarfExpressionEvaluator::_Evaluate()
|
||||||
case DW_OP_abs:
|
case DW_OP_abs:
|
||||||
{
|
{
|
||||||
target_addr_t value = _Pop();
|
target_addr_t value = _Pop();
|
||||||
if (fAddressSize == 4) {
|
if (fContext->AddressSize() == 4) {
|
||||||
int32 signedValue = (int32)value;
|
int32 signedValue = (int32)value;
|
||||||
_Push(signedValue >= 0 ? signedValue : -signedValue);
|
_Push(signedValue >= 0 ? signedValue : -signedValue);
|
||||||
} else {
|
} else {
|
||||||
|
@ -262,7 +258,7 @@ DwarfExpressionEvaluator::_Evaluate()
|
||||||
break;
|
break;
|
||||||
case DW_OP_neg:
|
case DW_OP_neg:
|
||||||
{
|
{
|
||||||
if (fAddressSize == 4)
|
if (fContext->AddressSize() == 4)
|
||||||
_Push(-(int32)_Pop());
|
_Push(-(int32)_Pop());
|
||||||
else
|
else
|
||||||
_Push(-(int64)_Pop());
|
_Push(-(int64)_Pop());
|
||||||
|
@ -351,15 +347,37 @@ DwarfExpressionEvaluator::_Evaluate()
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DW_OP_push_object_address:
|
case DW_OP_push_object_address:
|
||||||
if (!fObjectAddressValid)
|
{
|
||||||
|
target_addr_t address;
|
||||||
|
if (!fContext->GetObjectAddress(address))
|
||||||
throw EvaluationException();
|
throw EvaluationException();
|
||||||
_Push(fObjectAddress);
|
_Push(address);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case DW_OP_call_frame_cfa:
|
case DW_OP_call_frame_cfa:
|
||||||
if (!fFrameAddressValid)
|
{
|
||||||
|
target_addr_t address;
|
||||||
|
if (!fContext->GetFrameAddress(address))
|
||||||
throw EvaluationException();
|
throw EvaluationException();
|
||||||
_Push(fFrameAddress);
|
_Push(address);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
case DW_OP_fbreg:
|
||||||
|
{
|
||||||
|
target_addr_t address;
|
||||||
|
if (!fContext->GetFrameBaseAddress(address))
|
||||||
|
throw EvaluationException();
|
||||||
|
_Push(address + fDataReader.ReadSignedLEB128(0));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case DW_OP_form_tls_address:
|
||||||
|
{
|
||||||
|
target_addr_t address;
|
||||||
|
if (!fContext->GetTLSAddress(_Pop(), address))
|
||||||
|
throw EvaluationException();
|
||||||
|
_Push(address);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case DW_OP_regx:
|
case DW_OP_regx:
|
||||||
_PushRegister(fDataReader.ReadUnsignedLEB128(0), 0);
|
_PushRegister(fDataReader.ReadUnsignedLEB128(0), 0);
|
||||||
|
@ -371,18 +389,17 @@ DwarfExpressionEvaluator::_Evaluate()
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case DW_OP_form_tls_address:
|
|
||||||
// TODO:...
|
|
||||||
break;
|
|
||||||
|
|
||||||
case DW_OP_fbreg:
|
|
||||||
// TODO:...
|
|
||||||
break;
|
|
||||||
|
|
||||||
case DW_OP_call2:
|
case DW_OP_call2:
|
||||||
|
_Call(fDataReader.Read<uint16>(0), true);
|
||||||
|
break;
|
||||||
case DW_OP_call4:
|
case DW_OP_call4:
|
||||||
|
_Call(fDataReader.Read<uint32>(0), true);
|
||||||
|
break;
|
||||||
case DW_OP_call_ref:
|
case DW_OP_call_ref:
|
||||||
// TODO:...
|
if (fContext->AddressSize() == 4)
|
||||||
|
_Call(fDataReader.Read<uint32>(0), false);
|
||||||
|
else
|
||||||
|
_Call(fDataReader.Read<uint64>(0), false);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DW_OP_piece:
|
case DW_OP_piece:
|
||||||
|
@ -432,7 +449,7 @@ DwarfExpressionEvaluator::_DereferenceAddress(uint8 addressSize)
|
||||||
valueType = B_UINT32_TYPE;
|
valueType = B_UINT32_TYPE;
|
||||||
break;
|
break;
|
||||||
case 8:
|
case 8:
|
||||||
if (fAddressSize == 8) {
|
if (fContext->AddressSize() == 8) {
|
||||||
valueType = B_UINT64_TYPE;
|
valueType = B_UINT64_TYPE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -443,7 +460,8 @@ DwarfExpressionEvaluator::_DereferenceAddress(uint8 addressSize)
|
||||||
|
|
||||||
target_addr_t address = _Pop();
|
target_addr_t address = _Pop();
|
||||||
BVariant value;
|
BVariant value;
|
||||||
if (!fTargetInterface->ReadValueFromMemory(address, valueType, value)) {
|
if (!fContext->TargetInterface()->ReadValueFromMemory(address, valueType,
|
||||||
|
value)) {
|
||||||
throw EvaluationException();
|
throw EvaluationException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -466,7 +484,7 @@ DwarfExpressionEvaluator::_DereferenceAddressSpaceAddress(uint8 addressSize)
|
||||||
valueType = B_UINT32_TYPE;
|
valueType = B_UINT32_TYPE;
|
||||||
break;
|
break;
|
||||||
case 8:
|
case 8:
|
||||||
if (fAddressSize == 8) {
|
if (fContext->AddressSize() == 8) {
|
||||||
valueType = B_UINT64_TYPE;
|
valueType = B_UINT64_TYPE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -478,8 +496,8 @@ DwarfExpressionEvaluator::_DereferenceAddressSpaceAddress(uint8 addressSize)
|
||||||
target_addr_t address = _Pop();
|
target_addr_t address = _Pop();
|
||||||
target_addr_t addressSpace = _Pop();
|
target_addr_t addressSpace = _Pop();
|
||||||
BVariant value;
|
BVariant value;
|
||||||
if (!fTargetInterface->ReadValueFromMemory(addressSpace, address, valueType,
|
if (!fContext->TargetInterface()->ReadValueFromMemory(addressSpace, address,
|
||||||
value)) {
|
valueType, value)) {
|
||||||
throw EvaluationException();
|
throw EvaluationException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -491,8 +509,42 @@ void
|
||||||
DwarfExpressionEvaluator::_PushRegister(uint32 reg, target_addr_t offset)
|
DwarfExpressionEvaluator::_PushRegister(uint32 reg, target_addr_t offset)
|
||||||
{
|
{
|
||||||
BVariant value;
|
BVariant value;
|
||||||
if (!fTargetInterface->GetRegisterValue(reg, value))
|
if (!fContext->TargetInterface()->GetRegisterValue(reg, value))
|
||||||
throw EvaluationException();
|
throw EvaluationException();
|
||||||
|
|
||||||
_Push(value.ToUInt64());
|
_Push(value.ToUInt64());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
DwarfExpressionEvaluator::_Call(uint64 offset, bool local)
|
||||||
|
{
|
||||||
|
if (fDataReader.HasOverflow())
|
||||||
|
throw EvaluationException();
|
||||||
|
|
||||||
|
// get the expression to "call"
|
||||||
|
const void* block;
|
||||||
|
off_t size;
|
||||||
|
if (fContext->GetCallTarget(offset, local, block, size) != B_OK)
|
||||||
|
throw EvaluationException();
|
||||||
|
|
||||||
|
// no expression is OK, then this is just a no-op
|
||||||
|
if (block == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// save the current data reader state
|
||||||
|
DataReader savedReader = fDataReader;
|
||||||
|
|
||||||
|
// set the reader to the target expression
|
||||||
|
fDataReader.SetTo(block, size, savedReader.AddressSize());
|
||||||
|
|
||||||
|
// and evaluate it
|
||||||
|
try {
|
||||||
|
_Evaluate();
|
||||||
|
} catch (...) {
|
||||||
|
fDataReader = savedReader;
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
|
||||||
|
fDataReader = savedReader;
|
||||||
|
}
|
||||||
|
|
|
@ -13,11 +13,41 @@
|
||||||
class DwarfTargetInterface;
|
class DwarfTargetInterface;
|
||||||
|
|
||||||
|
|
||||||
|
class DwarfExpressionEvaluationContext {
|
||||||
|
public:
|
||||||
|
DwarfExpressionEvaluationContext(
|
||||||
|
DwarfTargetInterface* targetInterface,
|
||||||
|
uint8 addressSize);
|
||||||
|
virtual ~DwarfExpressionEvaluationContext();
|
||||||
|
|
||||||
|
DwarfTargetInterface* TargetInterface() const
|
||||||
|
{ return fTargetInterface; }
|
||||||
|
uint8 AddressSize() const { return fAddressSize; }
|
||||||
|
|
||||||
|
virtual bool GetObjectAddress(target_addr_t& _address) = 0;
|
||||||
|
virtual bool GetFrameAddress(target_addr_t& _address) = 0;
|
||||||
|
virtual bool GetFrameBaseAddress(target_addr_t& _address)
|
||||||
|
= 0;
|
||||||
|
virtual bool GetTLSAddress(target_addr_t localAddress,
|
||||||
|
target_addr_t& _address) = 0;
|
||||||
|
|
||||||
|
virtual status_t GetCallTarget(uint64 offset, bool local,
|
||||||
|
const void*& _block, off_t& _size) = 0;
|
||||||
|
// returns error, when an error resolving
|
||||||
|
// the entry occurs; returns B_OK and a NULL
|
||||||
|
// block, when the entry doesn't have a
|
||||||
|
// location attribute
|
||||||
|
|
||||||
|
private:
|
||||||
|
DwarfTargetInterface* fTargetInterface;
|
||||||
|
uint8 fAddressSize;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
class DwarfExpressionEvaluator {
|
class DwarfExpressionEvaluator {
|
||||||
public:
|
public:
|
||||||
DwarfExpressionEvaluator(
|
DwarfExpressionEvaluator(
|
||||||
DwarfTargetInterface* targetInterface,
|
DwarfExpressionEvaluationContext* context);
|
||||||
uint8 addressSize);
|
|
||||||
~DwarfExpressionEvaluator();
|
~DwarfExpressionEvaluator();
|
||||||
|
|
||||||
void SetObjectAddress(target_addr_t address);
|
void SetObjectAddress(target_addr_t address);
|
||||||
|
@ -39,16 +69,16 @@ private:
|
||||||
void _DereferenceAddressSpaceAddress(
|
void _DereferenceAddressSpaceAddress(
|
||||||
uint8 addressSize);
|
uint8 addressSize);
|
||||||
void _PushRegister(uint32 reg, target_addr_t offset);
|
void _PushRegister(uint32 reg, target_addr_t offset);
|
||||||
|
void _Call(uint64 offset, bool local);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
DwarfTargetInterface* fTargetInterface;
|
DwarfExpressionEvaluationContext* fContext;
|
||||||
target_addr_t* fStack;
|
target_addr_t* fStack;
|
||||||
size_t fStackSize;
|
size_t fStackSize;
|
||||||
size_t fStackCapacity;
|
size_t fStackCapacity;
|
||||||
DataReader fDataReader;
|
DataReader fDataReader;
|
||||||
target_addr_t fObjectAddress;
|
target_addr_t fObjectAddress;
|
||||||
target_addr_t fFrameAddress;
|
target_addr_t fFrameAddress;
|
||||||
uint8 fAddressSize;
|
|
||||||
bool fObjectAddressValid;
|
bool fObjectAddressValid;
|
||||||
bool fFrameAddressValid;
|
bool fFrameAddressValid;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue