changes made for CFG for alpha architecture and
[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 isAReturnInstruction(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 isAIndirectJumpInstruction(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 isACondBranchInstruction(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 isAJumpInstruction(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 isACallInstruction(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(process* fProcess,
90                              Address bAddress,
91                              unsigned fSize)
92         : addressProc(fProcess),
93           addressImage(fProcess->getImage()),baseAddress(bAddress),
94           range(fSize),currentAddress(bAddress) {}
95
96 AddressHandle::AddressHandle(Address cAddress,process* fProcess,
97                              Address bAddress,
98                              unsigned fSize)
99         : addressProc(fProcess),
100           addressImage(fProcess->getImage()),baseAddress(bAddress),
101           range(fSize),currentAddress(cAddress) {}
102
103 AddressHandle::AddressHandle(const AddressHandle& ah){
104         addressImage = ah.addressImage;
105         addressProc = ah.addressProc;
106         baseAddress = ah.baseAddress;
107         currentAddress = ah.currentAddress;
108         range = ah.range;
109 }
110 void AddressHandle::getMultipleJumpTargets(BPatch_Set<Address>& result){
111         while(hasMore()){
112                 instruction check = getInstruction();
113                 if((check.sethi.op == 0x0) && 
114                    (check.sethi.op2 == 0x4) &&
115                    (check.sethi.rd != 0x0))
116                 {
117                         register signed offset = check.sethi.imm22 << 10;
118                         check = getNextInstruction();
119                         if((check.resti.op == 0x2) &&
120                            (check.resti.op3 == 0x2) &&
121                            (check.resti.i == 0x1)){
122                                 register signed lowData = check.resti.simm13 & 0x3ff;
123                                 offset |= lowData;
124                                 setCurrentAddress((Address)offset);
125                                 for(;;){
126                                         check = getInstruction();
127                                         if(IS_VALID_INSN(check))
128                                                 break;
129                                         result += check.raw;
130                                         (*this)++;
131                                 }
132                                 return;
133                         }
134                 }
135                 (*this)--;
136         }
137 }
138 bool AddressHandle::delayInstructionSupported(){
139         return true;
140 }
141 bool AddressHandle::hasMore(){
142         if((currentAddress < (baseAddress + range )) &&
143            (currentAddress >= baseAddress))
144                 return true;
145         return false;
146 }
147 bool AddressHandle::hasPrev(){
148     if((currentAddress < (baseAddress + range )) &&
149        (currentAddress > baseAddress))
150         return true;
151     return false;
152 }
153 Address AddressHandle::prevAddress(){
154         Address ret = currentAddress-sizeof(instruction);
155         return ret;
156 }
157 Address AddressHandle::prevAddressOf(Address addr){
158         Address ret = addr - sizeof(instruction);
159         return ret;
160 }
161 Address AddressHandle::nextAddress(){
162         Address ret = currentAddress + sizeof(instruction);
163         return ret;
164 }
165 Address AddressHandle::nextAddressOf(Address addr){
166         Address ret = addr + sizeof(instruction);
167         return ret;
168 }
169 void AddressHandle::setCurrentAddress(Address addr){
170         currentAddress = addr;
171 }
172 unsigned AddressHandle::getInstructionCount(){
173         return range / sizeof(Word);
174 }
175 instruction AddressHandle::getInstruction(){
176         instruction ret;
177         ret.raw = addressImage->get_instruction(currentAddress);
178         return ret;
179 }
180 instruction AddressHandle::getNextInstruction(){
181         instruction ret;
182         ret.raw = addressImage->get_instruction(currentAddress+sizeof(instruction));
183         return ret;
184 }
185 instruction AddressHandle::getPrevInstruction(){
186         instruction ret;
187         ret.raw = addressImage->get_instruction(currentAddress-sizeof(instruction));
188         return ret;
189 }
190 Address AddressHandle::operator++(){
191         currentAddress += sizeof(instruction);
192         return currentAddress;
193 }
194 Address AddressHandle::operator--(){
195         currentAddress -= sizeof(instruction);
196         return currentAddress;
197 }
198 Address AddressHandle::operator++(int){
199         Address ret = currentAddress;
200         currentAddress += sizeof(instruction);
201         return ret;
202 }
203 Address AddressHandle::operator--(int){
204         Address ret = currentAddress;
205         currentAddress -= sizeof(instruction);
206         return ret;
207 }
208 Address AddressHandle::operator*(){
209         return currentAddress;
210 }