Add new tests for control flow graph functions, fixes for
[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 "common/h/Types.h"
7 #include "common/h/Vector.h"
8 #include "common/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                                 for(;;){
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 bool AddressHandle::hasPrev(){
146     if((currentAddress < (baseAddress + range )) &&
147        (currentAddress > baseAddress))
148         return true;
149     return false;
150 }
151 Address AddressHandle::prevAddress(){
152         Address ret = currentAddress-sizeof(instruction);
153         return ret;
154 }
155 Address AddressHandle::prevAddressOf(Address addr){
156         Address ret = addr - sizeof(instruction);
157         return ret;
158 }
159 Address AddressHandle::nextAddress(){
160         Address ret = currentAddress + sizeof(instruction);
161         return ret;
162 }
163 Address AddressHandle::nextAddressOf(Address addr){
164         Address ret = addr + sizeof(instruction);
165         return ret;
166 }
167 void AddressHandle::setCurrentAddress(Address addr){
168         currentAddress = addr;
169 }
170 unsigned AddressHandle::getInstructionCount(){
171         return range / sizeof(Word);
172 }
173 instruction AddressHandle::getInstruction(){
174         instruction ret;
175         ret.raw = addressImage->get_instruction(currentAddress);
176         return ret;
177 }
178 instruction AddressHandle::getNextInstruction(){
179         instruction ret;
180         ret.raw = addressImage->get_instruction(currentAddress+sizeof(instruction));
181         return ret;
182 }
183 instruction AddressHandle::getPrevInstruction(){
184         instruction ret;
185         ret.raw = addressImage->get_instruction(currentAddress-sizeof(instruction));
186         return ret;
187 }
188 Address AddressHandle::operator++(){
189         currentAddress += sizeof(instruction);
190         return currentAddress;
191 }
192 Address AddressHandle::operator--(){
193         currentAddress -= sizeof(instruction);
194         return currentAddress;
195 }
196 Address AddressHandle::operator++(int){
197         Address ret = currentAddress;
198         currentAddress += sizeof(instruction);
199         return ret;
200 }
201 Address AddressHandle::operator--(int){
202         Address ret = currentAddress;
203         currentAddress -= sizeof(instruction);
204         return ret;
205 }
206 Address AddressHandle::operator*(){
207         return currentAddress;
208 }