De-static some unnecessary statics
[dyninst.git] / instructionAPI / src / Operation.C
1 /*
2  * See the dyninst/COPYRIGHT file for copyright information.
3  * 
4  * We provide the Paradyn Tools (below described as "Paradyn")
5  * on an AS IS basis, and do not warrant its validity or performance.
6  * We reserve the right to update, modify, or discontinue this
7  * software at any time.  We shall have no obligation to supply such
8  * updates or modifications or any other form of support to you.
9  * 
10  * By your use of Paradyn, you understand and agree that we (or any
11  * other person or entity with proprietary rights in Paradyn) are
12  * under no obligation to provide either maintenance services,
13  * update services, notices of latent defects, or correction of
14  * defects for Paradyn.
15  * 
16  * This library is free software; you can redistribute it and/or
17  * modify it under the terms of the GNU Lesser General Public
18  * License as published by the Free Software Foundation; either
19  * version 2.1 of the License, or (at your option) any later version.
20  * 
21  * This library is distributed in the hope that it will be useful,
22  * but WITHOUT ANY WARRANTY; without even the implied warranty of
23  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
24  * Lesser General Public License for more details.
25  * 
26  * You should have received a copy of the GNU Lesser General Public
27  * License along with this library; if not, write to the Free Software
28  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
29  */
30
31 #define INSIDE_INSTRUCTION_API
32
33 #include "common/src/Types.h"
34
35 #include "Operation.h"
36 #include "common/src/arch-x86.h"
37 #include "entryIDs.h"
38 #include "common/src/Singleton.h"
39 #include "Register.h"
40 #include <map>
41 #include "common/src/singleton_object_pool.h"
42
43 using namespace NS_x86;
44 #include "BinaryFunction.h"
45 #include "Immediate.h"
46
47 namespace Dyninst
48 {
49   namespace InstructionAPI
50   {
51     RegisterAST::Ptr makeRegFromID(MachRegister regID, unsigned int low, unsigned int high)
52     {
53       return make_shared(singleton_object_pool<RegisterAST>::construct(regID, low, high));
54     }
55     RegisterAST::Ptr makeRegFromID(MachRegister regID)
56     {
57         return make_shared(singleton_object_pool<RegisterAST>::construct(regID, 0, regID.size() * 8));
58     }
59
60     Operation::Operation(entryID id, const char* mnem, Architecture arch)
61           : mnemonic(mnem), operationID(id), doneOtherSetup(true), doneFlagsSetup(true), archDecodedFrom(arch), prefixID(prefix_none)
62     {
63         switch(archDecodedFrom)
64         {
65             case Arch_x86:
66             case Arch_ppc32:
67                 addrWidth = u32;
68                 break;
69             default:
70                 addrWidth = u64;
71                 break;
72         }
73     }
74     
75     Operation::Operation(ia32_entry* e, ia32_prefixes* p, ia32_locations* l, Architecture arch) :
76       doneOtherSetup(false), doneFlagsSetup(false), archDecodedFrom(arch), prefixID(prefix_none)
77     
78     {
79       operationID = e->getID(l);
80       // Defaults for no size prefix
81       switch(archDecodedFrom)
82       {
83           case Arch_x86:
84           case Arch_ppc32:
85               addrWidth = u32;
86               break;
87           default:
88               addrWidth = u64;
89               break;
90       }
91       
92       if(p && p->getCount())
93       {
94         if (p->getPrefix(0) == PREFIX_REP || p->getPrefix(0) == PREFIX_REPNZ)
95         {
96             otherRead.insert(makeRegFromID((archDecodedFrom == Arch_x86) ? x86::df : x86_64::df));
97             otherRead.insert(makeRegFromID((archDecodedFrom == Arch_x86) ? x86::ecx : x86_64::rcx));
98             otherWritten.insert(makeRegFromID((archDecodedFrom == Arch_x86) ? x86::ecx : x86_64::rcx));
99             if(p->getPrefix(0) == PREFIX_REPNZ)
100             {
101                 otherRead.insert(makeRegFromID((archDecodedFrom == Arch_x86) ? x86::zf : x86_64::zf));
102                 prefixID = prefix_repnz;
103             }
104             else
105             {
106                 prefixID = prefix_rep;
107             }
108         }
109         else
110         {
111           prefixID = prefix_none;
112         }
113         int segPrefix = p->getPrefix(1);
114         switch(segPrefix)
115         {
116             case PREFIX_SEGCS:
117                 otherRead.insert(makeRegFromID((archDecodedFrom == Arch_x86) ? x86::cs : x86_64::cs));
118                 break;
119             case PREFIX_SEGDS:
120                 otherRead.insert(makeRegFromID((archDecodedFrom == Arch_x86) ? x86::ds : x86_64::ds));
121                 break;
122             case PREFIX_SEGES:
123                 otherRead.insert(makeRegFromID((archDecodedFrom == Arch_x86) ? x86::es : x86_64::es));
124                 break;
125             case PREFIX_SEGFS:
126                 otherRead.insert(makeRegFromID((archDecodedFrom == Arch_x86) ? x86::fs : x86_64::fs));
127                 break;
128             case PREFIX_SEGGS:
129                 otherRead.insert(makeRegFromID((archDecodedFrom == Arch_x86) ? x86::gs : x86_64::gs));
130                 break;
131             case PREFIX_SEGSS:
132                 otherRead.insert(makeRegFromID((archDecodedFrom == Arch_x86) ? x86::ss : x86_64::ss));
133                 break;
134         }
135         if(p->getAddrSzPrefix())
136         {
137             addrWidth = u16;
138         }
139       }
140     }
141
142     Operation::Operation(const Operation& o)
143     {
144       otherRead = o.otherRead;
145       otherWritten = o.otherWritten;
146       otherEffAddrsRead = o.otherEffAddrsRead;
147       otherEffAddrsWritten = o.otherEffAddrsWritten;
148       operationID = o.operationID;
149       doneOtherSetup = o.doneOtherSetup;
150       doneFlagsSetup = o.doneFlagsSetup;
151       archDecodedFrom = o.archDecodedFrom;
152       prefixID = prefix_none;
153       addrWidth = o.addrWidth;
154       
155     }
156     const Operation& Operation::operator=(const Operation& o)
157     {
158       otherRead = o.otherRead;
159       otherWritten = o.otherWritten;
160       otherEffAddrsRead = o.otherEffAddrsRead;
161       otherEffAddrsWritten = o.otherEffAddrsWritten;
162       operationID = o.operationID;
163       doneOtherSetup = o.doneOtherSetup;
164       doneFlagsSetup = o.doneFlagsSetup;
165       archDecodedFrom = o.archDecodedFrom;
166       prefixID = o.prefixID;
167       addrWidth = o.addrWidth;
168       return *this;
169     }
170     Operation::Operation()
171     {
172       operationID = e_No_Entry;
173       doneOtherSetup = false;
174       doneFlagsSetup = false;
175       archDecodedFrom = Arch_none;
176       prefixID = prefix_none;
177       addrWidth = u64;
178     }
179     
180     const Operation::registerSet&  Operation::implicitReads() const
181     {
182       SetUpNonOperandData(true);
183       
184       return otherRead;
185     }
186     const Operation::registerSet&  Operation::implicitWrites() const
187     {
188       SetUpNonOperandData(true);
189
190       return otherWritten;
191     }
192     bool Operation::isRead(Expression::Ptr candidate) const
193     {
194      
195         SetUpNonOperandData(candidate->isFlag());
196      
197       for(registerSet::const_iterator r = otherRead.begin();
198           r != otherRead.end();
199           ++r)
200       {
201         if(*candidate == *(*r))
202         {
203           return true;
204         }
205       }
206       for(VCSet::const_iterator e = otherEffAddrsRead.begin();
207           e != otherEffAddrsRead.end();
208           ++e)
209       {
210         if(*candidate == *(*e))
211         {
212           return true;
213         }
214       }
215       return false;
216     }
217     const Operation::VCSet& Operation::getImplicitMemReads() const
218     {
219       SetUpNonOperandData(true);
220       return otherEffAddrsRead;
221     }
222     const Operation::VCSet& Operation::getImplicitMemWrites() const
223     {
224       SetUpNonOperandData(true);
225       return otherEffAddrsWritten;
226     }
227
228     bool Operation::isWritten(Expression::Ptr candidate) const
229     {
230      
231         SetUpNonOperandData(candidate->isFlag());
232       
233       for(registerSet::const_iterator r = otherWritten.begin();
234           r != otherWritten.end();
235           ++r)
236       {
237         if(*candidate == *(*r))
238         {
239           return true;
240         }
241       }
242       for(VCSet::const_iterator e = otherEffAddrsWritten.begin();
243           e != otherEffAddrsWritten.end();
244           ++e)
245       {
246         if(*candidate == *(*e))
247         {
248           return true;
249         }
250       }
251       return false;
252     }
253           
254     std::string Operation::format() const
255     {
256         if(mnemonic != "")
257         {
258             return mnemonic;
259         }
260       dyn_hash_map<prefixEntryID, std::string>::const_iterator foundPrefix = prefixEntryNames_IAPI.find(prefixID);
261       dyn_hash_map<entryID, std::string>::const_iterator found = entryNames_IAPI.find(operationID);
262       std::string result;
263       if(foundPrefix != prefixEntryNames_IAPI.end())
264       {
265         result += (foundPrefix->second + " ");
266       }
267       if(found != entryNames_IAPI.end())
268       {
269         result += found->second;
270       }
271       else
272       {
273         result += "[INVALID]";
274       }
275       return result;
276     }
277
278     entryID Operation::getID() const
279     {
280       return operationID;
281     }
282
283     prefixEntryID Operation::getPrefixID() const
284     {
285       return prefixID;
286     }
287
288     struct OperationMaps
289     {
290     public:
291       OperationMaps(Architecture arch)
292       {
293           thePC.insert(RegisterAST::Ptr(new RegisterAST(MachRegister::getPC(arch))));
294           pcAndSP.insert(RegisterAST::Ptr(new RegisterAST(MachRegister::getPC(arch))));
295           pcAndSP.insert(RegisterAST::Ptr(new RegisterAST(MachRegister::getStackPointer(arch))));
296           stackPointer.insert(RegisterAST::Ptr(new RegisterAST(MachRegister::getStackPointer(arch))));
297           stackPointerAsExpr.insert(RegisterAST::Ptr(new RegisterAST(MachRegister::getStackPointer(arch))));
298           framePointer.insert(RegisterAST::Ptr(new RegisterAST(MachRegister::getFramePointer(arch))));
299           spAndBP.insert(RegisterAST::Ptr(new RegisterAST(MachRegister::getStackPointer(arch))));
300           spAndBP.insert(RegisterAST::Ptr(new RegisterAST(MachRegister::getFramePointer(arch))));
301           si.insert(RegisterAST::Ptr(new RegisterAST(arch == Arch_x86_64 ? x86_64::esi : x86::esi)));
302           di.insert(RegisterAST::Ptr(new RegisterAST(arch == Arch_x86_64 ? x86_64::edi : x86::edi)));
303           si_and_di.insert(RegisterAST::Ptr(new RegisterAST(arch == Arch_x86_64 ? x86_64::esi : x86::esi)));
304           si_and_di.insert(RegisterAST::Ptr(new RegisterAST(arch == Arch_x86_64 ? x86_64::edi : x86::edi)));
305         
306           nonOperandRegisterReads[e_call] = pcAndSP;
307           nonOperandRegisterReads[e_ret_near] = stackPointer;
308           nonOperandRegisterReads[e_ret_far] = stackPointer;
309           nonOperandRegisterReads[e_leave] = framePointer;
310           nonOperandRegisterReads[e_enter] = spAndBP;
311         
312           nonOperandRegisterWrites[e_call] = pcAndSP;
313           nonOperandRegisterWrites[e_ret_near] = pcAndSP;
314           nonOperandRegisterWrites[e_ret_far] = pcAndSP;
315           nonOperandRegisterWrites[e_leave] = spAndBP;
316           nonOperandRegisterWrites[e_enter] = spAndBP;
317           nonOperandRegisterWrites[e_loop] = thePC;
318           nonOperandRegisterWrites[e_loope] = thePC;
319           nonOperandRegisterWrites[e_loopn] = thePC;
320           nonOperandRegisterWrites[e_jb] = thePC;
321           nonOperandRegisterWrites[e_jb_jnaej_j] = thePC;
322         nonOperandRegisterWrites[e_jbe] = thePC;
323         nonOperandRegisterWrites[e_jcxz_jec] = thePC;
324         nonOperandRegisterWrites[e_jl] = thePC;
325         nonOperandRegisterWrites[e_jle] = thePC;
326         nonOperandRegisterWrites[e_jmp] = thePC;
327         nonOperandRegisterWrites[e_jnb] = thePC;
328         nonOperandRegisterWrites[e_jnb_jae_j] = thePC;
329         nonOperandRegisterWrites[e_jnbe] = thePC;
330         nonOperandRegisterWrites[e_jnl] = thePC;
331         nonOperandRegisterWrites[e_jnle] = thePC;
332         nonOperandRegisterWrites[e_jno] = thePC;
333         nonOperandRegisterWrites[e_jnp] = thePC;
334         nonOperandRegisterWrites[e_jns] = thePC;
335         nonOperandRegisterWrites[e_jnz] = thePC;
336         nonOperandRegisterWrites[e_jo] = thePC;
337         nonOperandRegisterWrites[e_jp] = thePC;
338         nonOperandRegisterWrites[e_js] = thePC;
339         nonOperandRegisterWrites[e_jz] = thePC;
340         nonOperandMemoryReads[e_pop] = stackPointerAsExpr;
341         nonOperandMemoryReads[e_popa] = stackPointerAsExpr;
342         nonOperandMemoryReads[e_popad] = stackPointerAsExpr;
343         nonOperandMemoryWrites[e_push] = stackPointerAsExpr;
344         nonOperandMemoryWrites[e_pusha] = stackPointerAsExpr;
345         nonOperandMemoryWrites[e_pushad] = stackPointerAsExpr;
346         nonOperandMemoryWrites[e_call] = stackPointerAsExpr;
347         nonOperandMemoryReads[e_ret_near] = stackPointerAsExpr;
348         nonOperandMemoryReads[e_ret_far] = stackPointerAsExpr;
349         nonOperandMemoryReads[e_leave] = stackPointerAsExpr;
350         nonOperandRegisterWrites[e_cmpsb] = si_and_di;
351         nonOperandRegisterWrites[e_cmpsd] = si_and_di;
352         nonOperandRegisterWrites[e_cmpsw] = si_and_di;
353         nonOperandRegisterWrites[e_movsb] = si_and_di;
354         nonOperandRegisterWrites[e_movsd] = si_and_di;
355         nonOperandRegisterWrites[e_movsw] = si_and_di;
356         nonOperandRegisterWrites[e_cmpsb] = si_and_di;
357         nonOperandRegisterWrites[e_cmpsd] = si_and_di;
358         nonOperandRegisterWrites[e_cmpsw] = si_and_di;
359         nonOperandRegisterWrites[e_insb] = di;
360         nonOperandRegisterWrites[e_insd] = di;
361         nonOperandRegisterWrites[e_insw] = di;
362         nonOperandRegisterWrites[e_stosb] = di;
363         nonOperandRegisterWrites[e_stosd] = di;
364         nonOperandRegisterWrites[e_stosw] = di;
365         nonOperandRegisterWrites[e_scasb] = di;
366         nonOperandRegisterWrites[e_scasd] = di;
367         nonOperandRegisterWrites[e_scasw] = di;
368         nonOperandRegisterWrites[e_lodsb] = si;
369         nonOperandRegisterWrites[e_lodsd] = si;
370         nonOperandRegisterWrites[e_lodsw] = si;
371         nonOperandRegisterWrites[e_outsb] = si;
372         nonOperandRegisterWrites[e_outsd] = si;
373         nonOperandRegisterWrites[e_outsw] = si;
374         
375       }
376       Operation::registerSet thePC;
377       Operation::registerSet pcAndSP;
378       Operation::registerSet stackPointer;
379       Operation::VCSet stackPointerAsExpr;
380       Operation::registerSet framePointer;
381       Operation::registerSet spAndBP;
382       Operation::registerSet si;
383       Operation::registerSet di;
384       Operation::registerSet si_and_di;
385       dyn_hash_map<entryID, Operation::registerSet > nonOperandRegisterReads;
386       dyn_hash_map<entryID, Operation::registerSet > nonOperandRegisterWrites;
387
388       dyn_hash_map<entryID, Operation::VCSet > nonOperandMemoryReads;
389       dyn_hash_map<entryID, Operation::VCSet > nonOperandMemoryWrites;
390     };
391     OperationMaps op_data_32(Arch_x86);
392     OperationMaps op_data_64(Arch_x86_64);
393     const OperationMaps& op_data(Architecture arch)
394     {
395         switch(arch)
396         {
397             case Arch_x86:
398                 return op_data_32;
399             case Arch_x86_64:
400                 return op_data_64;
401             default:
402                 return op_data_32;
403         }
404     }
405     void Operation::SetUpNonOperandData(bool needFlags) const
406     {
407         if(doneOtherSetup && doneFlagsSetup) return;
408 #if defined(arch_x86) || defined(arch_x86_64)      
409         dyn_hash_map<entryID, registerSet >::const_iterator foundRegs;
410       foundRegs = op_data(archDecodedFrom).nonOperandRegisterReads.find(operationID);
411       if(foundRegs != op_data(archDecodedFrom).nonOperandRegisterReads.end())
412       {
413           otherRead.insert(foundRegs->second.begin(), foundRegs->second.end());
414       }
415       foundRegs = op_data(archDecodedFrom).nonOperandRegisterWrites.find(operationID);
416       if(foundRegs != op_data(archDecodedFrom).nonOperandRegisterWrites.end())
417       {
418           otherWritten.insert(foundRegs->second.begin(), foundRegs->second.end());
419       }
420       dyn_hash_map<entryID, VCSet >::const_iterator foundMem;
421       foundMem = op_data(archDecodedFrom).nonOperandMemoryReads.find(operationID);
422       if(foundMem != op_data(archDecodedFrom).nonOperandMemoryReads.end())
423       {
424           otherEffAddrsRead.insert(foundMem->second.begin(), foundMem->second.end());
425       }
426       if(operationID == e_push)
427       {
428           BinaryFunction::funcT::Ptr adder(new BinaryFunction::addResult());
429                     // special case for push: we write at the new value of the SP.
430           Result dummy(addrWidth, 0);
431           Expression::Ptr push_addr(new BinaryFunction(
432                   *(op_data(archDecodedFrom).stackPointerAsExpr.begin()),
433           Immediate::makeImmediate(Result(s8, -(dummy.size()))),
434           addrWidth,
435           adder));
436                 
437           otherEffAddrsWritten.insert(push_addr);
438                   
439       }
440       else
441       {
442           foundMem = op_data(archDecodedFrom).nonOperandMemoryWrites.find(operationID);
443           if(foundMem != op_data(archDecodedFrom).nonOperandMemoryWrites.end())
444           {
445               otherEffAddrsWritten.insert(foundMem->second.begin(), foundMem->second.end());
446           }
447       }
448       if(needFlags && !doneFlagsSetup)
449       {
450         
451         dyn_hash_map<entryID, flagInfo>::const_iterator found = ia32_instruction::getFlagTable().find(operationID);
452         if(found != ia32_instruction::getFlagTable().end())
453         {
454           for(unsigned i = 0; i < found->second.readFlags.size(); i++)
455           {
456             switch(found->second.readFlags[i]) {
457             case x86::icf:
458               otherRead.insert(makeRegFromID((archDecodedFrom == Arch_x86) ? x86::cf : x86_64::cf));
459               break;
460             case x86::ipf:
461               otherRead.insert(makeRegFromID((archDecodedFrom == Arch_x86) ? x86::pf : x86_64::pf));
462               break;
463             case x86::iaf:
464               otherRead.insert(makeRegFromID((archDecodedFrom == Arch_x86) ? x86::af : x86_64::af));
465               break;
466             case x86::izf:
467               otherRead.insert(makeRegFromID((archDecodedFrom == Arch_x86) ? x86::zf : x86_64::zf));
468               break;
469             case x86::isf:
470               otherRead.insert(makeRegFromID((archDecodedFrom == Arch_x86) ? x86::sf : x86_64::sf));
471               break;
472             case x86::itf:
473               otherRead.insert(makeRegFromID((archDecodedFrom == Arch_x86) ? x86::tf : x86_64::tf));
474               break;
475             case x86::idf:
476               otherRead.insert(makeRegFromID((archDecodedFrom == Arch_x86) ? x86::df : x86_64::df));
477               break;
478             case x86::iof:
479               otherRead.insert(makeRegFromID((archDecodedFrom == Arch_x86) ? x86::of : x86_64::of));
480               break;
481             case x86::int_:
482               otherRead.insert(makeRegFromID((archDecodedFrom == Arch_x86) ? x86::nt_ : x86_64::nt_));
483               break;
484             case x86::iif_:
485               otherRead.insert(makeRegFromID((archDecodedFrom == Arch_x86) ? x86::if_ : x86_64::if_));
486               break;
487             default:
488               assert(0);
489             }
490           }
491           for(unsigned j = 0; j < found->second.writtenFlags.size(); j++)
492             {
493             switch(found->second.writtenFlags[j]) {
494             case x86::icf:
495               otherWritten.insert(makeRegFromID((archDecodedFrom == Arch_x86) ? x86::cf : x86_64::cf));
496               break;
497             case x86::ipf:
498               otherWritten.insert(makeRegFromID((archDecodedFrom == Arch_x86) ? x86::pf : x86_64::pf));
499               break;
500             case x86::iaf:
501               otherWritten.insert(makeRegFromID((archDecodedFrom == Arch_x86) ? x86::af : x86_64::af));
502               break;
503             case x86::izf:
504               otherWritten.insert(makeRegFromID((archDecodedFrom == Arch_x86) ? x86::zf : x86_64::zf));
505               break;
506             case x86::isf:
507               otherWritten.insert(makeRegFromID((archDecodedFrom == Arch_x86) ? x86::sf : x86_64::sf));
508               break;
509             case x86::itf:
510               otherWritten.insert(makeRegFromID((archDecodedFrom == Arch_x86) ? x86::tf : x86_64::tf));
511               break;
512             case x86::idf:
513               otherWritten.insert(makeRegFromID((archDecodedFrom == Arch_x86) ? x86::df : x86_64::df));
514               break;
515             case x86::iof:
516               otherWritten.insert(makeRegFromID((archDecodedFrom == Arch_x86) ? x86::of : x86_64::of));
517               break;
518             case x86::int_:
519               otherWritten.insert(makeRegFromID((archDecodedFrom == Arch_x86) ? x86::nt_ : x86_64::nt_));
520               break;
521             case x86::iif_:
522               otherWritten.insert(makeRegFromID((archDecodedFrom == Arch_x86) ? x86::if_ : x86_64::if_));
523               break;
524             default:
525                fprintf(stderr, "ERROR: unhandled entry %s\n", found->second.writtenFlags[j].name().c_str());
526                assert(0);
527             }
528           }
529         }
530         doneFlagsSetup = true;
531       }
532       doneOtherSetup = true;
533 #else
534       (void) needFlags; //Silence warnings
535 #endif //defined(arch_x86) || defined(arch_x86_64)
536     return;
537     }
538   }
539
540 };