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 12 CfaContext::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 26 CfaContext::~CfaContext() 27 { 28 delete fRuleSet; 29 delete fInitialRuleSet; 30 } 31 32 33 void 34 CfaContext::SetLocation(target_addr_t targetLocation, 35 target_addr_t initialLocation) 36 { 37 fTargetLocation = targetLocation; 38 fLocation = initialLocation; 39 } 40 41 42 status_t 43 CfaContext::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 53 status_t 54 CfaContext::SaveInitialRuleSet() 55 { 56 fInitialRuleSet = fRuleSet->Clone(); 57 if (fInitialRuleSet == NULL) 58 return B_NO_MEMORY; 59 return B_OK; 60 } 61 62 63 status_t 64 CfaContext::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 76 status_t 77 CfaContext::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 90 void 91 CfaContext::SetLocation(target_addr_t location) 92 { 93 fLocation = location; 94 } 95 96 97 void 98 CfaContext::SetCodeAlignment(uint32 alignment) 99 { 100 fCodeAlignment = alignment; 101 } 102 103 104 void 105 CfaContext::SetDataAlignment(int32 alignment) 106 { 107 fDataAlignment = alignment; 108 } 109 110 111 void 112 CfaContext::SetReturnAddressRegister(uint32 reg) 113 { 114 fReturnAddressRegister = reg; 115 } 116 117 118 void 119 CfaContext::RestoreRegisterRule(uint32 reg) 120 { 121 if (CfaRule* rule = RegisterRule(reg)) { 122 if (fInitialRuleSet != NULL) 123 *rule = *fInitialRuleSet->RegisterRule(reg); 124 } 125 } 126