* Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
* Distributed under the terms of the MIT License.
*/
#include <new>
#include "CfaContext.h"
CfaContext::CfaContext()
:
fTargetLocation(0),
fLocation(0),
fCodeAlignment(0),
fDataAlignment(0),
fReturnAddressRegister(0),
fRuleSet(NULL),
fInitialRuleSet(NULL),
fRuleSetStack(10)
{
}
CfaContext::~CfaContext()
{
delete fRuleSet;
delete fInitialRuleSet;
}
void
CfaContext::SetLocation(target_addr_t targetLocation,
target_addr_t initialLocation)
{
fTargetLocation = targetLocation;
fLocation = initialLocation;
}
status_t
CfaContext::Init(uint32 registerCount)
{
fRuleSet = new(std::nothrow) CfaRuleSet;
if (fRuleSet == NULL)
return B_NO_MEMORY;
return fRuleSet->Init(registerCount);
}
status_t
CfaContext::SaveInitialRuleSet()
{
fInitialRuleSet = fRuleSet->Clone();
if (fInitialRuleSet == NULL)
return B_NO_MEMORY;
return B_OK;
}
status_t
CfaContext::PushRuleSet()
{
CfaRuleSet* ruleSet = fRuleSet->Clone();
if (ruleSet == NULL || !fRuleSetStack.AddItem(ruleSet)) {
delete ruleSet;
return B_NO_MEMORY;
}
return B_OK;
}
status_t
CfaContext::PopRuleSet()
{
if (fRuleSetStack.IsEmpty())
return B_BAD_DATA;
delete fRuleSet;
fRuleSet = fRuleSetStack.RemoveItemAt(
fRuleSetStack.CountItems() - 1);
return B_OK;
}
void
CfaContext::SetLocation(target_addr_t location)
{
fLocation = location;
}
void
CfaContext::SetCodeAlignment(uint32 alignment)
{
fCodeAlignment = alignment;
}
void
CfaContext::SetDataAlignment(int32 alignment)
{
fDataAlignment = alignment;
}
void
CfaContext::SetReturnAddressRegister(uint32 reg)
{
fReturnAddressRegister = reg;
}
void
CfaContext::RestoreRegisterRule(uint32 reg)
{
if (CfaRule* rule = RegisterRule(reg)) {
if (fInitialRuleSet != NULL)
*rule = *fInitialRuleSet->RegisterRule(reg);
}
}