changes made for CFG for alpha architecture and
[dyninst.git] / dyninstAPI / src / AddressHandle-power.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         if((i.xlform.op == BCLRop) &&
25            (i.xlform.xo == BCLRxop) && 
26            (i.xlform.bt & 0x10) && (i.xlform.bt & 0x4))
27                 return true;
28         return false;
29 }
30
31 /** is the instruction an indirect jump instruction 
32   * @param i the instruction value 
33   */
34 bool isAIndirectJumpInstruction(const instruction i,AddressHandle ah){
35         if((i.xlform.op == BCLRop) && (i.xlform.xo == BCCTRxop) &&
36            !i.xlform.lk && (i.xlform.bt & 0x10) && (i.xlform.bt & 0x4))
37                 return true;
38
39         if((i.xlform.op == BCLRop) && (i.xlform.xo == BCLRxop) &&
40            (i.xlform.bt & 0x10) && (i.xlform.bt & 0x4)){
41                 --ah;--ah;
42                 if(!ah.hasMore())
43                         return false;
44                 instruction j = ah.getInstruction();
45                 if((j.xfxform.op == 31) && (j.xfxform.xo == 467) &&
46                    (j.xfxform.spr == 0x100))
47                         return true;
48         }
49         return false;
50 }
51
52 /** is the instruction a conditional branch instruction 
53   * @param i the instruction value 
54   */ 
55 bool isACondBranchInstruction(const instruction i){
56         if((i.bform.op == BCop) && !i.bform.lk &&
57            !((i.bform.bo & 0x10) && (i.bform.bo & 0x4)))
58                 return true;
59         return false;
60 }
61 /** is the instruction an unconditional branch instruction 
62   * @param i the instruction value 
63   */
64 bool isAJumpInstruction(const instruction i){
65         if((i.iform.op == Bop) && !i.iform.lk)
66                 return true;
67         if((i.bform.op == BCop) && !i.bform.lk &&
68            (i.bform.bo & 0x10) && (i.bform.bo & 0x4))
69                 return true;
70         return false;
71 }
72 /** is the instruction a call instruction 
73   * @param i the instruction value 
74   */
75 bool isACallInstruction(const instruction i){
76         cout << "CALL called\n";
77         if(i.iform.lk && 
78            ((i.iform.op == Bop) || (i.bform.op == BCop) ||
79             ((i.xlform.op == BCLRop) && 
80              ((i.xlform.xo == 16) || (i.xlform.xo == 528))))){
81                 cout << "TIKIR : found CALL\n";
82                 return true;
83         }
84         return false;
85 }
86 /** function which returns the offset of control transfer instructions
87   * @param i the instruction value 
88   */
89 Address getBranchTargetAddress(const instruction i,Address pos){
90         Address ret = 0;
91         if((i.iform.op == Bop) || (i.bform.op == BCop)){
92                 int disp = 0;
93                 if(i.iform.op == Bop)
94                         disp = i.iform.li;
95                 else if(i.bform.op == BCop)
96                         disp = i.bform.bd;
97                 disp <<= 2;
98                 if(i.iform.aa)
99                         ret = (Address)disp;
100                 else
101                         ret = (Address)(pos+disp);
102         }
103         return (Address)ret;
104 }
105
106 //Address Handle used by flowGraph which wraps the instructions
107 //and supply enough operation to iterate over the instrcution sequence.
108
109 AddressHandle::AddressHandle(process* fProcess,
110                              Address bAddress,
111                              unsigned fSize)
112         : addressProc(fProcess),
113           addressImage(fProcess->getImage()),baseAddress(bAddress),
114           range(fSize),currentAddress(bAddress) {}
115
116 AddressHandle::AddressHandle(Address cAddress,process* fProcess,
117                              Address bAddress,
118                              unsigned fSize)
119         : addressProc(fProcess),
120           addressImage(fProcess->getImage()),baseAddress(bAddress),
121           range(fSize),currentAddress(cAddress) {}
122
123 AddressHandle::AddressHandle(const AddressHandle& ah){
124         addressImage = ah.addressImage;
125         addressProc = ah.addressProc;
126         baseAddress = ah.baseAddress;
127         currentAddress = ah.currentAddress;
128         range = ah.range;
129 }
130 void AddressHandle::getMultipleJumpTargets(BPatch_Set<Address>& result){
131
132         (*this)--;
133         Address initialAddress = currentAddress;
134         Address TOC_address = (addressImage->getObject()).getTOCoffset();
135
136         instruction check;
137         Address jumpStartAddress = 0;
138         while(hasMore()){
139                 check = getInstruction();
140                 if((check.dform.op == Lop) && (check.dform.ra == 2)){
141                         jumpStartAddress = 
142                                 (Address)(TOC_address + check.dform.d_or_si);
143                         break;
144                 }
145                 (*this)--;
146         }
147         (*this)--;
148         Address adjustEntry = 0;
149         check = getInstruction();
150         if((check.dform.op == Lop))
151                 adjustEntry = check.dform.d_or_si;
152
153         Address tableStartAddress = 0;
154         while(hasMore()){
155                 instruction check = getInstruction();
156                 if((check.dform.op == Lop) && (check.dform.ra == 2)){
157                         tableStartAddress = 
158                                 (Address)(TOC_address + check.dform.d_or_si);
159                         break;
160                 }
161                 (*this)--;
162         }
163
164         setCurrentAddress(initialAddress);
165         int maxSwitch = 0;
166         while(hasMore()){
167                 instruction check = getInstruction();
168                 if((check.bform.op == BCop) && 
169                    !check.bform.aa && !check.bform.lk){
170                         (*this)--;
171                         check = getInstruction();
172                         if(10 != check.dform.op)
173                                 break;
174                         maxSwitch = check.dform.d_or_si + 1;
175                         break;
176                 }
177                 (*this)--;
178         }
179         if(!maxSwitch){
180                 result += (initialAddress + sizeof(instruction));
181                 return;
182         }
183
184         Address jumpStart = 
185                 (Address)addressImage->get_instruction(jumpStartAddress);
186         Address tableStart = 
187                 (Address)addressImage->get_instruction(tableStartAddress);
188
189         for(int i=0;i<maxSwitch;i++){
190                 Address tableEntry = adjustEntry + tableStart + (i * sizeof(instruction));
191                 int jumpOffset = (int)addressImage->get_instruction(tableEntry);
192                 result += (Address)(jumpStart+jumpOffset);
193         }
194 }
195
196 bool AddressHandle::delayInstructionSupported(){
197         return false;
198 }
199 bool AddressHandle::hasMore(){
200         if((currentAddress < (baseAddress + range )) &&
201            (currentAddress >= baseAddress))
202                 return true;
203         return false;
204 }
205 bool AddressHandle::hasPrev(){
206     if((currentAddress < (baseAddress + range )) &&
207        (currentAddress > baseAddress))
208         return true;
209     return false;
210 }
211 Address AddressHandle::prevAddress(){
212         Address ret = currentAddress-sizeof(instruction);
213         return ret;
214 }
215 Address AddressHandle::prevAddressOf(Address addr){
216         Address ret = addr - sizeof(instruction);
217         return ret;
218 }
219 Address AddressHandle::nextAddress(){
220         Address ret = currentAddress + sizeof(instruction);
221         return ret;
222 }
223 Address AddressHandle::nextAddressOf(Address addr){
224         Address ret = addr + sizeof(instruction);
225         return ret;
226 }
227 void AddressHandle::setCurrentAddress(Address addr){
228         currentAddress = addr;
229 }
230 unsigned AddressHandle::getInstructionCount(){
231         return range / sizeof(instruction);
232 }
233 instruction AddressHandle::getInstruction(){
234         instruction ret;
235         ret.raw = addressImage->get_instruction(currentAddress);
236         return ret;
237 }
238 instruction AddressHandle::getNextInstruction(){
239         instruction ret;
240         ret.raw = addressImage->get_instruction(currentAddress+sizeof(instruction));
241         return ret;
242 }
243 instruction AddressHandle::getPrevInstruction(){
244         instruction ret;
245         ret.raw = addressImage->get_instruction(currentAddress-sizeof(instruction));
246         return ret;
247 }
248 Address AddressHandle::operator++(){
249         currentAddress += sizeof(instruction);
250         return currentAddress;
251 }
252 Address AddressHandle::operator--(){
253         currentAddress -= sizeof(instruction);
254         return currentAddress;
255 }
256 Address AddressHandle::operator++(int){
257         Address ret = currentAddress;
258         currentAddress += sizeof(instruction);
259         return ret;
260 }
261 Address AddressHandle::operator--(int){
262         Address ret = currentAddress;
263         currentAddress -= sizeof(instruction);
264         return ret;
265 }
266 Address AddressHandle::operator*(){
267         return currentAddress;
268 }