Addition of source files related to control flow graph etc
[dyninst.git] / dyninstAPI / src / AddressHandle-sparc.C
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <assert.h>
4 #include <string.h>
5
6 #include "util/h/Types.h"
7 #include "util/h/Vector.h"
8 #include "util/h/Dictionary.h"
9
10 #include "arch.h"
11 #include "util.h"
12 #include "process.h"
13 #include "symtab.h"
14 #include "instPoint.h"
15 #include "AddressHandle.h"
16
17 #include "BPatch_Set.h"
18
19 //some more function used to identify the properties of the instruction
20 /** is the instruction used to return from the functions
21   * @param i the instruction value 
22   */
23 bool isReturn(const instruction i){
24
25         if((i.resti.op == 0x2) && (i.resti.op3 == 0x38) &&
26            (i.resti.rd == 0) && (i.resti.i == 0x1) &&
27            ((i.resti.rs1 == 0xf) || (i.resti.rs1 == 0x1f)) &&
28            ((i.resti.simm13 == 8) || (i.resti.simm13 == 12)))
29                 return true;
30         return false;
31 }
32
33 /** is the instruction an indirect jump instruction 
34   * @param i the instruction value 
35   */
36 bool isLocalIndirectJump(const instruction i){
37
38         if((i.resti.op == 0x2) && (i.resti.op3 == 0x38) &&
39            (i.resti.rd == 0) && (i.resti.rs1 != 0xf) && 
40            (i.resti.rs1 != 0x1f))
41                 return true;
42         return false;
43 }
44
45 /** is the instruction a conditional branch instruction 
46   * @param i the instruction value 
47   */ 
48 bool isLocalCondBranch(const instruction i){
49         if((i.branch.op == 0) &&
50            (i.branch.op2 == 2 || i.branch.op2 == 6) &&
51            (i.branch.cond != 0) && (i.branch.cond != 8))
52                 return true;
53         return false;
54 }
55 /** is the instruction an unconditional branch instruction 
56   * @param i the instruction value 
57   */
58 bool isLocalJump(const instruction i){
59         if((i.branch.op == 0) &&
60            (i.branch.op2 == 2 || i.branch.op2 == 6) &&
61            (i.branch.cond == 8))
62                 return true;
63         return false;
64 }
65 /** is the instruction a call instruction 
66   * @param i the instruction value 
67   */
68 bool isLocalCall(const instruction i){
69         if(i.call.op == 0x1)
70                 return true;
71         return false;
72 }
73 /** function which returns the offset of control transfer instructions
74   * @param i the instruction value 
75   */
76 Address getBranchTargetAddress(const instruction i,Address pos){
77         int ret;
78         if(i.branch.op == 0)
79                 ret = i.branch.disp22;
80         else if(i.call.op == 0x1)
81                 ret = i.call.disp30;
82         ret <<= 2;
83         return (Address)(ret+pos);
84 }
85
86 //Address Handle used by flowGraph which wraps the instructions
87 //and supply enough operation to iterate over the instrcution sequence.
88
89 AddressHandle::AddressHandle(image* fImage,
90                              Address bAddress,
91                              unsigned fSize)
92         : addressImage(fImage),baseAddress(bAddress),
93           range(fSize),currentAddress(bAddress) {}
94
95 AddressHandle::AddressHandle(Address cAddress,image* fImage,
96                              Address bAddress,
97                              unsigned fSize)
98         : addressImage(fImage),baseAddress(bAddress),
99           range(fSize),currentAddress(cAddress) {}
100
101 AddressHandle::AddressHandle(const AddressHandle& ah){
102         addressImage = ah.addressImage;
103         baseAddress = ah.baseAddress;
104         currentAddress = ah.currentAddress;
105         range = ah.range;
106 }
107 void AddressHandle::getMultipleJumpTargets(BPatch_Set<Address>& result){
108         while(hasMore()){
109                 instruction check = getInstruction();
110                 if((check.sethi.op == 0x0) && 
111                    (check.sethi.op2 == 0x4) &&
112                    (check.sethi.rd != 0x0))
113                 {
114                         register signed offset = check.sethi.imm22 << 10;
115                         check = getNextInstruction();
116                         if((check.resti.op == 0x2) &&
117                            (check.resti.op3 == 0x2) &&
118                            (check.resti.i == 0x1)){
119                                 register signed lowData = check.resti.simm13 & 0x3ff;
120                                 offset |= lowData;
121                                 setCurrentAddress((Address)offset);
122                                 while(hasMore()){
123                                         check = getInstruction();
124                                         if(IS_VALID_INSN(check))
125                                                 break;
126                                         result += check.raw;
127                                         (*this)++;
128                                 }
129                                 return;
130                         }
131                 }
132                 (*this)--;
133         }
134 }
135 bool AddressHandle::delayInstructionSupported(){
136         return true;
137 }
138
139 bool AddressHandle::hasMore(){
140         if((currentAddress < (baseAddress + range )) &&
141            (currentAddress >= baseAddress))
142                 return true;
143         return false;
144 }
145 Address AddressHandle::prevAddress(){
146         Address ret = currentAddress-sizeof(instruction);
147         return ret;
148 }
149 Address AddressHandle::prevAddressOf(Address addr){
150         Address ret = addr - sizeof(instruction);
151         return ret;
152 }
153 Address AddressHandle::nextAddress(){
154         Address ret = currentAddress + sizeof(instruction);
155         return ret;
156 }
157 Address AddressHandle::nextAddressOf(Address addr){
158         Address ret = addr + sizeof(instruction);
159         return ret;
160 }
161 void AddressHandle::setCurrentAddress(Address addr){
162         currentAddress = addr;
163 }
164 unsigned AddressHandle::getInstructionCount(){
165         return range / sizeof(Word);
166 }
167 instruction AddressHandle::getInstruction(){
168         instruction ret;
169         ret.raw = addressImage->get_instruction(currentAddress);
170         return ret;
171 }
172 instruction AddressHandle::getNextInstruction(){
173         instruction ret;
174         ret.raw = addressImage->get_instruction(currentAddress+sizeof(instruction));
175         return ret;
176 }
177 instruction AddressHandle::getPrevInstruction(){
178         instruction ret;
179         ret.raw = addressImage->get_instruction(currentAddress-sizeof(instruction));
180         return ret;
181 }
182 Address AddressHandle::operator++(){
183         currentAddress += sizeof(instruction);
184         return currentAddress;
185 }
186 Address AddressHandle::operator--(){
187         currentAddress -= sizeof(instruction);
188         return currentAddress;
189 }
190 Address AddressHandle::operator++(int){
191         Address ret = currentAddress;
192         currentAddress += sizeof(instruction);
193         return ret;
194 }
195 Address AddressHandle::operator--(int){
196         Address ret = currentAddress;
197         currentAddress -= sizeof(instruction);
198         return ret;
199 }
200 Address AddressHandle::operator*(){
201         return currentAddress;
202 }