Update copyright to LGPL on all files
[dyninst.git] / dyninstAPI / src / BPatch_memoryAccessAdapter.C
1 /*
2  * Copyright (c) 1996-2009 Barton P. Miller
3  * 
4  * We provide the Paradyn Parallel Performance Tools (below
5  * described as "Paradyn") on an AS IS basis, and do not warrant its
6  * validity or performance.  We reserve the right to update, modify,
7  * or discontinue this software at any time.  We shall have no
8  * obligation to supply such updates or modifications or any other
9  * form of support to you.
10  * 
11  * By your use of Paradyn, you understand and agree that we (or any
12  * other person or entity with proprietary rights in Paradyn) are
13  * under no obligation to provide either maintenance services,
14  * update services, notices of latent defects, or correction of
15  * defects for Paradyn.
16  * 
17  * This library is free software; you can redistribute it and/or
18  * modify it under the terms of the GNU Lesser General Public
19  * License as published by the Free Software Foundation; either
20  * version 2.1 of the License, or (at your option) any later version.
21  * 
22  * This library is distributed in the hope that it will be useful,
23  * but WITHOUT ANY WARRANTY; without even the implied warranty of
24  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
25  * Lesser General Public License for more details.
26  * 
27  * You should have received a copy of the GNU Lesser General Public
28  * License along with this library; if not, write to the Free Software
29  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
30  */
31
32 #include "BPatch_memoryAccessAdapter.h"
33 #include "BPatch_memoryAccess_NP.h"
34 #include "Instruction.h"
35 #include "arch.h"
36 using namespace Dyninst;
37 using namespace InstructionAPI;
38
39
40 BPatch_memoryAccess* BPatch_memoryAccessAdapter::convert(Instruction::Ptr insn,
41                                                          Address current, bool is64)
42 {
43   static unsigned int log2[] = { 0, 0, 1, 1, 2, 2, 2, 2, 3 };
44     
45   // TODO 16-bit registers
46     
47   int nac = 0;
48     
49   ia32_memacc mac[3];
50   ia32_condition cnd;
51   ia32_instruction i(mac, &cnd);
52     
53   const unsigned char* addr = reinterpret_cast<const unsigned char*>(insn->ptr());
54   BPatch_memoryAccess* bmap = BPatch_memoryAccess::none;
55
56   ia32_set_mode_64(is64);
57   
58   ia32_decode(IA32_DECODE_MEMACCESS|IA32_DECODE_CONDITION, addr, i);
59   
60   bool first = true;
61
62   for(int j=0; j<3; ++j) {
63     ia32_memacc& mac = const_cast<ia32_memacc&>(i.getMac(j));
64     const ia32_condition& cond = i.getCond();
65     int bmapcond = cond.is ? cond.tttn : -1;
66     if(mac.is) {
67
68       // here, we can set the correct address for RIP-relative addressing
69       if (mac.regs[0] == mRIP) {
70         mac.imm = current + insn->size() + mac.imm;
71       }
72
73       if(first) {
74         if(mac.prefetch) {
75           if(mac.prefetchlvl > 0) // Intel
76             bmap = new BPatch_memoryAccess(NULL, current,
77                                            false, false,
78                                            mac.imm, mac.regs[0], mac.regs[1], mac.scale,
79                                            0, -1, -1, 0,
80                                            bmapcond, false, mac.prefetchlvl);
81           else // AMD
82             bmap = new BPatch_memoryAccess(NULL, current,
83                                            false, false,
84                                            mac.imm, mac.regs[0], mac.regs[1], mac.scale,
85                                            0, -1, -1, 0,
86                                            bmapcond, false, mac.prefetchstt + IA32AMDprefetch);
87         }
88         else switch(mac.sizehack) { // translation to pseudoregisters
89         case 0:
90           bmap = new BPatch_memoryAccess(NULL, current,
91                                          mac.read, mac.write,
92                                          mac.size, mac.imm, mac.regs[0], mac.regs[1], mac.scale, 
93                                          bmapcond, mac.nt);
94           break;
95         case shREP: // use ECX register to compute final size as mac.size * ECX
96           bmap = new BPatch_memoryAccess(NULL, current,
97                                          mac.read, mac.write,
98                                          mac.imm, mac.regs[0], mac.regs[1], mac.scale,
99                                          0, -1, 1 , log2[mac.size],
100                                          bmapcond, false);
101           break;
102         case shREPESCAS:
103           bmap = new BPatch_memoryAccess(NULL, current,
104                                          mac.read, mac.write,
105                                          mac.imm, mac.regs[0], mac.regs[1], mac.scale,
106                                          0, -1, IA32_ESCAS, log2[mac.size],
107                                          bmapcond, false);
108           break;
109         case shREPNESCAS:
110           bmap = new BPatch_memoryAccess(NULL, current,
111                                          mac.read, mac.write,
112                                          mac.imm, mac.regs[0], mac.regs[1], mac.scale,
113                                          0, -1, IA32_NESCAS, log2[mac.size],
114                                          bmapcond, false);
115           break;
116         case shREPECMPS:
117           bmap = new BPatch_memoryAccess(NULL, current,
118                                          mac.read, mac.write,
119                                          mac.imm, mac.regs[0], mac.regs[1], mac.scale,
120                                          0, -1, IA32_ECMPS, log2[mac.size],
121                                          bmapcond, false);
122           break;
123         case shREPNECMPS:
124           bmap = new BPatch_memoryAccess(NULL, current,
125                                          mac.read, mac.write,
126                                          mac.imm, mac.regs[0], mac.regs[1], mac.scale,
127                                          0, -1, IA32_NECMPS, log2[mac.size],
128                                          bmapcond, false);
129           break;
130         default:
131           assert(!"Unknown size hack");
132         }
133         first = false;
134       }
135       else
136         switch(mac.sizehack) { // translation to pseudoregisters
137         case 0:
138           bmap->set2nd(mac.read, mac.write, mac.size, mac.imm,
139                        mac.regs[0], mac.regs[1], mac.scale);
140           break;
141         case shREP: // use ECX register to compute final size as mac.size * ECX
142           bmap->set2nd(mac.read, mac.write,
143                        mac.imm, mac.regs[0], mac.regs[1], mac.scale,
144                        0, -1, 1 , log2[mac.size],
145                        bmapcond, false);
146           break;
147         case shREPESCAS:
148         case shREPNESCAS:
149           assert(!"Cannot happen");
150           break;
151         case shREPECMPS:
152           bmap->set2nd(mac.read, mac.write,
153                        mac.imm, mac.regs[0], mac.regs[1], mac.scale,
154                        0, -1, IA32_ECMPS, log2[mac.size],
155                        bmapcond, false);
156           break;
157         case shREPNECMPS:
158           //fprintf(stderr, "In set2nd[shREPNECMPS]!!!\n");
159           bmap->set2nd(mac.read, mac.write,
160                        mac.imm, mac.regs[0], mac.regs[1], mac.scale,
161                        0, -1, IA32_NECMPS, log2[mac.size],
162                        bmapcond, false);
163           break;
164         default:
165           assert(!"Unknown size hack");
166         }
167       ++nac;
168     }
169   }
170   assert(nac < 3);
171   return bmap;
172 }
173
174
175 void BPatch_memoryAccessAdapter::visit(BinaryFunction* b)
176 {
177 }
178
179
180 void BPatch_memoryAccessAdapter::visit(Dereference* d)
181 {
182 }
183
184 void BPatch_memoryAccessAdapter::visit(RegisterAST* r)
185 {
186 }
187
188 void BPatch_memoryAccessAdapter::visit(Immediate* i)
189 {
190 }
191