1/*
2 * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
3 * Distributed under the terms of the MIT License.
4 */
5
6
7#include <new>
8
9#include "CfaContext.h"
10
11
12CfaContext::CfaContext()
13	:
14	fTargetLocation(0),
15	fLocation(0),
16	fCodeAlignment(0),
17	fDataAlignment(0),
18	fReturnAddressRegister(0),
19	fRuleSet(NULL),
20	fInitialRuleSet(NULL),
21	fRuleSetStack(10, true)
22{
23}
24
25
26CfaContext::~CfaContext()
27{
28	delete fRuleSet;
29	delete fInitialRuleSet;
30}
31
32
33void
34CfaContext::SetLocation(target_addr_t targetLocation,
35	target_addr_t initialLocation)
36{
37	fTargetLocation = targetLocation;
38	fLocation = initialLocation;
39}
40
41
42status_t
43CfaContext::Init(uint32 registerCount)
44{
45	fRuleSet = new(std::nothrow) CfaRuleSet;
46	if (fRuleSet == NULL)
47		return B_NO_MEMORY;
48
49	return fRuleSet->Init(registerCount);
50}
51
52
53status_t
54CfaContext::SaveInitialRuleSet()
55{
56	fInitialRuleSet = fRuleSet->Clone();
57	if (fInitialRuleSet == NULL)
58		return B_NO_MEMORY;
59	return B_OK;
60}
61
62
63status_t
64CfaContext::PushRuleSet()
65{
66	CfaRuleSet* ruleSet = fRuleSet->Clone();
67	if (ruleSet == NULL || !fRuleSetStack.AddItem(ruleSet)) {
68		delete ruleSet;
69		return B_NO_MEMORY;
70	}
71
72	return B_OK;
73}
74
75
76status_t
77CfaContext::PopRuleSet()
78{
79	if (fRuleSetStack.IsEmpty())
80		return B_BAD_DATA;
81
82	delete fRuleSet;
83	fRuleSet = fRuleSetStack.RemoveItemAt(
84		fRuleSetStack.CountItems() - 1);
85
86	return B_OK;
87}
88
89
90void
91CfaContext::SetLocation(target_addr_t location)
92{
93	fLocation = location;
94}
95
96
97void
98CfaContext::SetCodeAlignment(uint32 alignment)
99{
100	fCodeAlignment = alignment;
101}
102
103
104void
105CfaContext::SetDataAlignment(int32 alignment)
106{
107	fDataAlignment = alignment;
108}
109
110
111void
112CfaContext::SetReturnAddressRegister(uint32 reg)
113{
114	fReturnAddressRegister = reg;
115}
116
117
118void
119CfaContext::RestoreRegisterRule(uint32 reg)
120{
121	if (CfaRule* rule = RegisterRule(reg)) {
122		if (fInitialRuleSet != NULL)
123			*rule = *fInitialRuleSet->RegisterRule(reg);
124	}
125}
126