Annotate intentional switch fallthrough
[dyninst.git] / instructionAPI / src / InstructionDecoder-x86.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 #include "InstructionDecoder-x86.h"
35 #include "Expression.h"
36 #include "common/src/arch-x86.h"
37 #include "Register.h"
38 #include "Dereference.h"
39 #include "Immediate.h" 
40 #include "BinaryFunction.h"
41 #include "common/src/singleton_object_pool.h"
42
43 using namespace std;
44 using namespace NS_x86;
45 namespace Dyninst
46 {
47     namespace InstructionAPI
48     {
49     
50         bool readsOperand(unsigned int opsema, unsigned int i)
51         {
52             switch(opsema) {
53                 case s1R2R:
54                     return (i == 0 || i == 1);
55                 case s1R:
56                 case s1RW:
57                     return i == 0;
58                 case s1W:
59                     return false;
60                 case s1W2RW:
61                 case s1W2R:   // second operand read, first operand written (e.g. mov)
62                     return i == 1;
63                 case s1RW2R:  // two operands read, first written (e.g. add)
64                 case s1RW2RW: // e.g. xchg
65                 case s1R2RW:
66                     return i == 0 || i == 1;
67                 case s1W2R3R: // e.g. imul
68                 case s1W2RW3R: // some mul
69                 case s1W2R3RW: // (stack) push & pop
70                     return i == 1 || i == 2;
71                 case s1W2W3R: // e.g. les
72                     return i == 2;
73                 case s1RW2R3R: // shld/shrd
74                 case s1RW2RW3R: // [i]div, cmpxch8b
75                 case s1R2R3R:
76                     return i == 0 || i == 1 || i == 2;
77                     break;
78                 case sNONE:
79                 default:
80                     return false;
81             }
82       
83         }
84       
85         bool writesOperand(unsigned int opsema, unsigned int i)
86         {
87             switch(opsema) {
88                 case s1R2R:
89                 case s1R:
90                     return false;
91                 case s1RW:
92                 case s1W:
93                     case s1W2R:   // second operand read, first operand written (e.g. mov)
94                         case s1RW2R:  // two operands read, first written (e.g. add)
95                             case s1W2R3R: // e.g. imul
96                                 case s1RW2R3R: // shld/shrd
97                                     return i == 0;
98                 case s1R2RW:
99                     return i == 1;
100                 case s1W2RW:
101                     case s1RW2RW: // e.g. xchg
102                         case s1W2RW3R: // some mul
103                             case s1W2W3R: // e.g. les
104                                 case s1RW2RW3R: // [i]div, cmpxch8b
105                                     return i == 0 || i == 1;
106                                     case s1W2R3RW: // (stack) push & pop
107                                         return i == 0 || i == 2;
108                 case sNONE:
109                 default:
110                     return false;
111             }
112         }
113
114
115     
116     INSTRUCTION_EXPORT InstructionDecoder_x86::InstructionDecoder_x86(Architecture a) :
117       InstructionDecoderImpl(a),
118     locs(NULL),
119     decodedInstruction(NULL),
120     sizePrefixPresent(false)
121     {
122       if(a == Arch_x86_64) setMode(true);
123       
124     }
125     INSTRUCTION_EXPORT InstructionDecoder_x86::~InstructionDecoder_x86()
126     {
127         if(decodedInstruction) decodedInstruction->~ia32_instruction();
128         free(decodedInstruction);
129         if(locs) locs->~ia32_locations();
130         free(locs);
131
132     }
133     static const unsigned char modrm_use_sib = 4;
134     
135     INSTRUCTION_EXPORT void InstructionDecoder_x86::setMode(bool is64)
136     {
137         ia32_set_mode_64(is64);
138     }
139     
140       Expression::Ptr InstructionDecoder_x86::makeSIBExpression(const InstructionDecoder::buffer& b)
141     {
142         unsigned scale;
143         Register index;
144         Register base;
145         Result_Type registerType = ia32_is_mode_64() ? u64 : u32;
146
147         decode_SIB(locs->sib_byte, scale, index, base);
148
149         Expression::Ptr scaleAST(make_shared(singleton_object_pool<Immediate>::construct(Result(u8, dword_t(scale)))));
150         Expression::Ptr indexAST(make_shared(singleton_object_pool<RegisterAST>::construct(makeRegisterID(index, registerType,
151                                     locs->rex_x))));
152         Expression::Ptr baseAST;
153         if(base == 0x05)
154         {
155             switch(locs->modrm_mod)
156             {
157                 case 0x00:
158                     baseAST = decodeImmediate(op_d, b.start + locs->sib_position + 1);
159                     break;
160                     case 0x01: {
161                         MachRegister reg;
162                         if (locs->rex_b)
163                             reg = x86_64::r13;
164                         else
165                           reg = MachRegister::getFramePointer(m_Arch);
166                         
167                         baseAST = makeAddExpression(make_shared(singleton_object_pool<RegisterAST>::construct(reg)),
168                                                     decodeImmediate(op_b, b.start + locs->sib_position + 1),
169                                                     registerType);
170                         break;
171                     }
172                     case 0x02: {
173                         MachRegister reg;
174                         if (locs->rex_b)
175                             reg = x86_64::r13;
176                         else
177                             reg = MachRegister::getFramePointer(m_Arch);
178
179                         baseAST = makeAddExpression(make_shared(singleton_object_pool<RegisterAST>::construct(reg)), 
180                                                     decodeImmediate(op_d, b.start + locs->sib_position + 1),
181                                                     registerType);
182                         break;
183                     }
184                 case 0x03:
185                 default:
186                     assert(0);
187                     break;
188             };
189         }
190         else
191         {
192             baseAST = make_shared(singleton_object_pool<RegisterAST>::construct(makeRegisterID(base, 
193                                                                                                registerType,
194                                                                                                locs->rex_b)));
195         }
196         if(index == 0x04 && (!(ia32_is_mode_64()) || !(locs->rex_x)))
197         {
198             return baseAST;
199         }
200         return makeAddExpression(baseAST, makeMultiplyExpression(indexAST, scaleAST, registerType), registerType);
201     }
202
203       Expression::Ptr InstructionDecoder_x86::makeModRMExpression(const InstructionDecoder::buffer& b,
204                                                                   unsigned int opType)
205     {
206        unsigned int regType = op_d;
207         Result_Type aw = ia32_is_mode_64() ? u32 : u64;
208         if(ia32_is_mode_64())
209         {
210             regType = op_q;
211         }
212         Expression::Ptr e =
213             makeRegisterExpression(makeRegisterID(locs->modrm_rm, regType, (locs->rex_b == 1)));
214         switch(locs->modrm_mod)
215         {
216             case 0:
217                 if(locs->modrm_rm == modrm_use_sib) {
218                     e = makeSIBExpression(b);
219                 }
220                 if(locs->modrm_rm == 0x5 && !addrSizePrefixPresent)
221                 {
222                     assert(locs->opcode_position > -1);
223                     if(ia32_is_mode_64())
224                     {
225                         e = makeAddExpression(makeRegisterExpression(x86_64::rip),
226                                             getModRMDisplacement(b), aw);
227                     }
228                     else
229                     {
230                         e = getModRMDisplacement(b);
231                     }
232         
233                 }
234                 if(locs->modrm_rm == 0x6 && addrSizePrefixPresent)
235                 {
236                     e = getModRMDisplacement(b);
237                 }
238                 if(opType == op_lea)
239                 {
240                     return e;
241                 }
242                 return makeDereferenceExpression(e, makeSizeType(opType));
243                 assert(0);
244                 break;
245             case 1:
246             case 2:
247             {
248                 if(locs->modrm_rm == modrm_use_sib) {
249                     e = makeSIBExpression(b);
250                 }
251                 Expression::Ptr disp_e = makeAddExpression(e, getModRMDisplacement(b), aw);
252                 if(opType == op_lea)
253                 {
254                     return disp_e;
255                 }
256                 return makeDereferenceExpression(disp_e, makeSizeType(opType));
257             }
258             assert(0);
259             break;
260             case 3:
261                 return makeRegisterExpression(makeRegisterID(locs->modrm_rm, opType, (locs->rex_b == 1)));
262             default:
263                 return Expression::Ptr();
264         
265         };
266         // can't get here, but make the compiler happy...
267         assert(0);
268         return Expression::Ptr();
269     }
270
271     Expression::Ptr InstructionDecoder_x86::decodeImmediate(unsigned int opType, const unsigned char* immStart, 
272                                                             bool isSigned)
273     {
274         switch(opType)
275         {
276             case op_b:
277                 return Immediate::makeImmediate(Result(isSigned ? s8 : u8 ,*(const byte_t*)(immStart)));
278                 break;
279             case op_d:
280                 return Immediate::makeImmediate(Result(isSigned ? s32 : u32,*(const dword_t*)(immStart)));
281             case op_w:
282                 return Immediate::makeImmediate(Result(isSigned ? s16 : u16,*(const word_t*)(immStart)));
283                 break;
284             case op_q:
285                 return Immediate::makeImmediate(Result(isSigned ? s64 : u64,*(const int64_t*)(immStart)));
286                 break;
287             case op_v:
288               if (locs->rex_w) {
289                     return Immediate::makeImmediate(Result(isSigned ? s64 : u64,*(const int64_t*)(immStart)));
290               }
291               //FALLTHROUGH
292             case op_z:
293         // 32 bit mode & no prefix, or 16 bit mode & prefix => 32 bit
294         // 16 bit mode, no prefix or 32 bit mode, prefix => 16 bit
295               if(!sizePrefixPresent)
296               {
297                 return Immediate::makeImmediate(Result(isSigned ? s32 : u32,*(const dword_t*)(immStart)));
298               }
299               else
300               {
301                 return Immediate::makeImmediate(Result(isSigned ? s16 : u16,*(const word_t*)(immStart)));
302               }
303               break;
304             case op_p:
305         // 32 bit mode & no prefix, or 16 bit mode & prefix => 48 bit
306         // 16 bit mode, no prefix or 32 bit mode, prefix => 32 bit
307                 if(!sizePrefixPresent)
308                 {
309                     return Immediate::makeImmediate(Result(isSigned ? s48 : u48,*(const int64_t*)(immStart)));
310                 }
311                 else
312                 {
313                     return Immediate::makeImmediate(Result(isSigned ? s32 : u32,*(const dword_t*)(immStart)));
314                 }
315         
316                 break;
317             case op_a:
318             case op_dq:
319             case op_pd:
320             case op_ps:
321             case op_s:
322             case op_si:
323             case op_lea:
324             case op_allgprs:
325             case op_512:
326             case op_c:
327                 assert(!"Can't happen: opType unexpected for valid ways to decode an immediate");
328                 return Expression::Ptr();
329             default:
330                 assert(!"Can't happen: opType out of range");
331                 return Expression::Ptr();
332         }
333     }
334     
335     Expression::Ptr InstructionDecoder_x86::getModRMDisplacement(const InstructionDecoder::buffer& b)
336     {
337         int disp_pos;
338
339         if(locs->sib_position != -1)
340         {
341             disp_pos = locs->sib_position + 1;
342         }
343         else
344         {
345             disp_pos = locs->modrm_position + 1;
346         }
347         switch(locs->modrm_mod)
348         {
349             case 1:
350                 return make_shared(singleton_object_pool<Immediate>::construct(Result(s8, (*(const byte_t*)(b.start +
351                         disp_pos)))));
352                 break;
353             case 2:
354                 if(sizePrefixPresent)
355                 {
356                     return make_shared(singleton_object_pool<Immediate>::construct(Result(s16, *((const word_t*)(b.start +
357                             disp_pos)))));
358                 }
359                 else
360                 {
361                     return make_shared(singleton_object_pool<Immediate>::construct(Result(s32, *((const dword_t*)(b.start +
362                             disp_pos)))));
363                 }
364                 break;
365             case 0:
366                 // In 16-bit mode, the word displacement is modrm r/m 6
367                 if(sizePrefixPresent)
368                 {
369                     if(locs->modrm_rm == 6)
370                     {
371                         return make_shared(singleton_object_pool<Immediate>::construct(Result(s16,
372                                            *((const dword_t*)(b.start + disp_pos)))));
373                     }
374                     // TODO FIXME; this was decoding wrong, but I'm not sure
375                     // why...
376                     else if (locs->modrm_rm == 5) {
377                         assert(b.start + disp_pos + 4 <= b.end);
378                         return make_shared(singleton_object_pool<Immediate>::construct(Result(s32,
379                                            *((const dword_t*)(b.start + disp_pos)))));
380                     } else {
381                         assert(b.start + disp_pos + 1 <= b.end);
382                         return make_shared(singleton_object_pool<Immediate>::construct(Result(s8, 0)));
383                     }
384                     break;
385                 }
386                 // ...and in 32-bit mode, the dword displacement is modrm r/m 5
387                 else
388                 {
389                     if(locs->modrm_rm == 5)
390                     {
391                         assert(b.start + disp_pos + 4 <= b.end);
392                         return make_shared(singleton_object_pool<Immediate>::construct(Result(s32,
393                                            *((const dword_t*)(b.start + disp_pos)))));
394                     }
395                     else
396                     {
397                         assert(b.start + disp_pos + 1 <= b.end);
398                         return make_shared(singleton_object_pool<Immediate>::construct(Result(s8, 0)));
399                     }
400                     break;
401                 }
402             default:
403                 assert(b.start + disp_pos + 1 <= b.end);
404                 return make_shared(singleton_object_pool<Immediate>::construct(Result(s8, 0)));
405                 break;
406         }
407     }
408
409     enum intelRegBanks
410     {
411         b_8bitNoREX = 0,
412         b_16bit,
413         b_32bit,
414         b_segment,
415         b_64bit,
416         b_xmm,
417         b_xmmhigh,
418         b_mm,
419         b_cr,
420         b_dr,
421         b_tr,
422         b_amd64ext,
423         b_8bitWithREX,
424         b_fpstack,
425         amd64_ext_8,
426         amd64_ext_16,
427         amd64_ext_32
428     };
429     static MachRegister IntelRegTable32[][8] = {
430         {
431             x86::al, x86::cl, x86::dl, x86::bl, x86::ah, x86::ch, x86::dh, x86::bh
432         },
433         {
434             x86::ax, x86::cx, x86::dx, x86::bx, x86::sp, x86::bp, x86::si, x86::di
435         },
436         {
437             x86::eax, x86::ecx, x86::edx, x86::ebx, x86::esp, x86::ebp, x86::esi, x86::edi
438         },
439         {
440            x86::es, x86::cs, x86::ss, x86::ds, x86::fs, x86::gs, InvalidReg, InvalidReg
441         },
442         {
443             x86_64::rax, x86_64::rcx, x86_64::rdx, x86_64::rbx, x86_64::rsp, x86_64::rbp, x86_64::rsi, x86_64::rdi
444         },
445         {
446             x86::xmm0, x86::xmm1, x86::xmm2, x86::xmm3, x86::xmm4, x86::xmm5, x86::xmm6, x86::xmm7
447         },
448         {
449             x86_64::xmm8, x86_64::xmm9, x86_64::xmm10, x86_64::xmm11, x86_64::xmm12, x86_64::xmm13, x86_64::xmm14, x86_64::xmm15
450         },
451         {
452             x86::mm0, x86::mm1, x86::mm2, x86::mm3, x86::mm4, x86::mm5, x86::mm6, x86::mm7
453         },
454         {
455             x86::cr0, x86::cr1, x86::cr2, x86::cr3, x86::cr4, x86::cr5, x86::cr6, x86::cr7
456         },
457         {
458             x86::dr0, x86::dr1, x86::dr2, x86::dr3, x86::dr4, x86::dr5, x86::dr6, x86::dr7
459         },
460         {
461             x86::tr0, x86::tr1, x86::tr2, x86::tr3, x86::tr4, x86::tr5, x86::tr6, x86::tr7
462         },
463         {
464             x86_64::r8, x86_64::r9, x86_64::r10, x86_64::r11, x86_64::r12, x86_64::r13, x86_64::r14, x86_64::r15
465         },
466         {
467             x86_64::al, x86_64::cl, x86_64::dl, x86_64::bl, x86_64::spl, x86_64::bpl, x86_64::sil, x86_64::dil
468         },
469         {
470             x86::st0, x86::st1, x86::st2, x86::st3, x86::st4, x86::st5, x86::st6, x86::st7
471         }
472
473     };
474     static MachRegister IntelRegTable64[][8] = {
475         {
476             x86_64::al, x86_64::cl, x86_64::dl, x86_64::bl, x86_64::ah, x86_64::ch, x86_64::dh, x86_64::bh
477         },
478         {
479             x86_64::ax, x86_64::cx, x86_64::dx, x86_64::bx, x86_64::sp, x86_64::bp, x86_64::si, x86_64::di
480         },
481         {
482             x86_64::eax, x86_64::ecx, x86_64::edx, x86_64::ebx, x86_64::esp, x86_64::ebp, x86_64::esi, x86_64::edi
483         },
484         {
485             x86_64::es, x86_64::cs, x86_64::ss, x86_64::ds, x86_64::fs, x86_64::gs, InvalidReg, InvalidReg
486         },
487         {
488             x86_64::rax, x86_64::rcx, x86_64::rdx, x86_64::rbx, x86_64::rsp, x86_64::rbp, x86_64::rsi, x86_64::rdi
489         },
490         {
491             x86_64::xmm0, x86_64::xmm1, x86_64::xmm2, x86_64::xmm3, x86_64::xmm4, x86_64::xmm5, x86_64::xmm6, x86_64::xmm7
492         },
493         {
494             x86_64::xmm8, x86_64::xmm9, x86_64::xmm10, x86_64::xmm11, x86_64::xmm12, x86_64::xmm13, x86_64::xmm14, x86_64::xmm15
495         },
496         {
497             x86_64::mm0, x86_64::mm1, x86_64::mm2, x86_64::mm3, x86_64::mm4, x86_64::mm5, x86_64::mm6, x86_64::mm7
498         },
499         {
500             x86_64::cr0, x86_64::cr1, x86_64::cr2, x86_64::cr3, x86_64::cr4, x86_64::cr5, x86_64::cr6, x86_64::cr7
501         },
502         {
503             x86_64::dr0, x86_64::dr1, x86_64::dr2, x86_64::dr3, x86_64::dr4, x86_64::dr5, x86_64::dr6, x86_64::dr7
504         },
505         {
506             x86_64::tr0, x86_64::tr1, x86_64::tr2, x86_64::tr3, x86_64::tr4, x86_64::tr5, x86_64::tr6, x86_64::tr7
507         },
508         {
509             x86_64::r8, x86_64::r9, x86_64::r10, x86_64::r11, x86_64::r12, x86_64::r13, x86_64::r14, x86_64::r15
510         },
511         {
512             x86_64::al, x86_64::cl, x86_64::dl, x86_64::bl, x86_64::spl, x86_64::bpl, x86_64::sil, x86_64::dil
513         },
514         {
515             x86_64::st0, x86_64::st1, x86_64::st2, x86_64::st3, x86_64::st4, x86_64::st5, x86_64::st6, x86_64::st7
516         },
517         {
518             x86_64::r8b, x86_64::r9b, x86_64::r10b, x86_64::r11b, x86_64::r12b, x86_64::r13b, x86_64::r14b, x86_64::r15b 
519         },
520         {
521             x86_64::r8w, x86_64::r9w, x86_64::r10w, x86_64::r11w, x86_64::r12w, x86_64::r13w, x86_64::r14w, x86_64::r15w 
522         },
523         {
524             x86_64::r8d, x86_64::r9d, x86_64::r10d, x86_64::r11d, x86_64::r12d, x86_64::r13d, x86_64::r14d, x86_64::r15d 
525         }
526
527     };
528
529   /* Uses the appropriate lookup table based on the 
530      decoder architecture */
531   class IntelRegTable_access {
532     public:
533         inline MachRegister operator()(Architecture arch,
534                                        intelRegBanks bank,
535                                        int index)
536         {
537             assert(index >= 0 && index < 8);
538     
539             if(arch == Arch_x86_64)
540                 return IntelRegTable64[bank][index];
541             else if(arch == Arch_x86) 
542             {
543               assert(bank <= b_fpstack);
544               return IntelRegTable32[bank][index];
545             }
546             
547             else
548                 assert(0);
549             return IntelRegTable32[bank][index];
550         }
551
552   };
553   static IntelRegTable_access IntelRegTable;
554
555       bool InstructionDecoder_x86::isDefault64Insn()
556       {
557         switch(m_Operation->getID())
558         {
559         case e_jmp:
560         case e_pop:
561         case e_push:
562         case e_call:
563           return true;
564         default:
565           return false;
566         }
567         
568       }
569       
570
571     MachRegister InstructionDecoder_x86::makeRegisterID(unsigned int intelReg, unsigned int opType,
572                                         bool isExtendedReg)
573     {
574         MachRegister retVal;
575         
576
577         if(isExtendedReg)
578         {
579             switch(opType)
580             {
581                 case op_q:  
582                     retVal = IntelRegTable(m_Arch,b_amd64ext,intelReg);
583                     break;
584                 case op_d:
585                     retVal = IntelRegTable(m_Arch,amd64_ext_32,intelReg);
586                     break;
587                 case op_w:
588                     retVal = IntelRegTable(m_Arch,amd64_ext_16,intelReg);
589                     break;
590                 case op_b:
591                     retVal = IntelRegTable(m_Arch,amd64_ext_8,intelReg);
592                     break;
593                 case op_v:
594                     if (locs->rex_w)
595                         retVal = IntelRegTable(m_Arch, b_amd64ext, intelReg);
596                     else if (!sizePrefixPresent)
597                         retVal = IntelRegTable(m_Arch, b_amd64ext, intelReg);
598                     else
599                         retVal = IntelRegTable(m_Arch, amd64_ext_16, intelReg);
600                     break;      
601                 case op_p:
602                 case op_z:
603                     if (!sizePrefixPresent)
604                         retVal = IntelRegTable(m_Arch, amd64_ext_32, intelReg);
605                     else
606                         retVal = IntelRegTable(m_Arch, amd64_ext_16, intelReg);
607                     break;
608                 default:
609                     fprintf(stderr, "%d\n", opType);
610                     fprintf(stderr, "%s\n",  decodedInstruction->getEntry()->name(locs));
611                     assert(0 && "opType=" && opType);
612             }
613         }
614         /* Promotion to 64-bit only applies to the operand types
615            that are varible (c,v,z). Ignoring c and z because they
616            do the right thing on 32- and 64-bit code.
617         else if(locs->rex_w)
618         {
619             // AMD64 with 64-bit operands
620             retVal = IntelRegTable[b_64bit][intelReg];
621         }
622         */
623         else
624         {
625             switch(opType)
626             {
627                 case op_v:
628                   if(locs->rex_w || isDefault64Insn())
629                         retVal = IntelRegTable(m_Arch,b_64bit,intelReg);
630                     else
631                         retVal = IntelRegTable(m_Arch,b_32bit,intelReg);
632                     break;
633                 case op_b:
634                     if (locs->rex_position == -1) {
635                         retVal = IntelRegTable(m_Arch,b_8bitNoREX,intelReg);
636                     } else {
637                         retVal = IntelRegTable(m_Arch,b_8bitWithREX,intelReg);
638                     }
639                     break;
640                 case op_q:
641                     retVal = IntelRegTable(m_Arch,b_64bit,intelReg);
642                     break;
643                 case op_w:
644                     retVal = IntelRegTable(m_Arch,b_16bit,intelReg);
645                     break;
646                 case op_f:
647                 case op_dbl:
648                     retVal = IntelRegTable(m_Arch,b_fpstack,intelReg);
649                     break;
650                 case op_d:
651                 case op_si:
652                     retVal = IntelRegTable(m_Arch,b_32bit,intelReg);
653                     break;
654                 default:
655                     retVal = IntelRegTable(m_Arch,b_32bit,intelReg);
656                     break;
657             }
658         }
659
660         if (!ia32_is_mode_64()) {
661           if ((retVal.val() & 0x00ffffff) == 0x0001000c)
662             assert(0);
663         }
664
665         return MachRegister((retVal.val() & ~retVal.getArchitecture()) | m_Arch);
666     }
667     
668     Result_Type InstructionDecoder_x86::makeSizeType(unsigned int opType)
669     {
670         switch(opType)
671         {
672             case op_b:
673             case op_c:
674                 return u8;
675             case op_d:
676             case op_ss:
677             case op_allgprs:
678             case op_si:
679                 return u32;
680             case op_w:
681             case op_a:
682                 return u16;
683             case op_q:
684             case op_sd:
685                 return u64;
686             case op_v:
687             case op_lea:
688             case op_z:
689               if(!ia32_is_mode_64() ^ sizePrefixPresent)
690                 {
691                     return u32;
692                 }
693                 else
694                 {
695                     return u16;
696                 }
697                 break;
698             case op_y:
699                 if(ia32_is_mode_64())
700                         return u64;
701                 else
702                         return u32;
703                 break;
704             case op_p:
705                 // book says operand size; arch-x86 says word + word * operand size
706                 if(!ia32_is_mode_64() ^ sizePrefixPresent)
707                 {
708                     return u48;
709                 }
710                 else
711                 {
712                     return u32;
713                 }
714             case op_dq:
715                 return u64;
716             case op_512:
717                 return m512;
718             case op_pi:
719             case op_ps:
720             case op_pd:
721                 return dbl128;
722             case op_s:
723                 return u48;
724             case op_f:
725                 return sp_float;
726             case op_dbl:
727                 return dp_float;
728             case op_14:
729                 return m14;
730             default:
731                 assert(!"Can't happen!");
732                 return u8;
733         }
734     }
735
736
737     bool InstructionDecoder_x86::decodeOneOperand(const InstructionDecoder::buffer& b,
738                                                   const ia32_operand& operand,
739                                                   int & imm_index, /* immediate operand index */
740                                                   const Instruction* insn_to_complete, 
741                                                   bool isRead, bool isWritten)
742     {
743        bool isCFT = false;
744       bool isCall = false;
745       bool isConditional = false;
746       InsnCategory cat = insn_to_complete->getCategory();
747       if(cat == c_BranchInsn || cat == c_CallInsn)
748         {
749           isCFT = true;
750           if(cat == c_CallInsn)
751             {
752               isCall = true;
753             }
754         }
755       if (cat == c_BranchInsn && insn_to_complete->getOperation().getID() != e_jmp) {
756         isConditional = true;
757       }
758
759       unsigned int optype = operand.optype;
760       if (sizePrefixPresent && 
761           ((optype == op_v) ||
762            (optype == op_z))) {
763         optype = op_w;
764       }
765       if(optype == op_y) {
766           if(ia32_is_mode_64() && locs->rex_w)
767                   optype = op_q;
768           else
769                   optype = op_d;
770       }
771                 switch(operand.admet)
772                 {
773                     case 0:
774                     // No operand
775                     {
776 /*                        fprintf(stderr, "ERROR: Instruction with mismatched operands. Raw bytes: ");
777                         for(unsigned int i = 0; i < decodedInstruction->getSize(); i++) {
778                             fprintf(stderr, "%x ", b.start[i]);
779                         }
780                         fprintf(stderr, "\n");*/
781                         assert(!"Mismatched number of operands--check tables");
782                         return false;
783                     }
784                     case am_A:
785                     {
786                         // am_A only shows up as a far call/jump.  Position 1 should be universally safe.
787                         Expression::Ptr addr(decodeImmediate(optype, b.start + 1));
788                         insn_to_complete->addSuccessor(addr, isCall, false, false, false);
789                     }
790                     break;
791                     case am_C:
792                     {
793                         Expression::Ptr op(makeRegisterExpression(IntelRegTable(m_Arch,b_cr,locs->modrm_reg)));
794                         insn_to_complete->appendOperand(op, isRead, isWritten);
795                     }
796                     break;
797                     case am_D:
798                     {
799                         Expression::Ptr op(makeRegisterExpression(IntelRegTable(m_Arch,b_dr,locs->modrm_reg)));
800                         insn_to_complete->appendOperand(op, isRead, isWritten);
801                     }
802                     break;
803                     case am_E:
804                     // am_M is like am_E, except that mod of 0x03 should never occur (am_M specified memory,
805                     // mod of 0x03 specifies direct register access).
806                     case am_M:
807                     // am_R is the inverse of am_M; it should only have a mod of 3
808                     case am_R:
809                     // can be am_R or am_M      
810                     case am_RM: 
811                         if(isCFT)
812                         {
813                           insn_to_complete->addSuccessor(makeModRMExpression(b, optype), isCall, true, false, false);
814                         }
815                         else
816                         {
817                           insn_to_complete->appendOperand(makeModRMExpression(b, optype), isRead, isWritten);
818                         }
819                     break;
820                     case am_F:
821                     {
822                         Expression::Ptr op(makeRegisterExpression(x86::flags));
823                         insn_to_complete->appendOperand(op, isRead, isWritten);
824                     }
825                     break;
826                     case am_G:
827                     {
828                         Expression::Ptr op(makeRegisterExpression(makeRegisterID(locs->modrm_reg,
829                                 optype, locs->rex_r)));
830                         insn_to_complete->appendOperand(op, isRead, isWritten);
831                     }
832                     break;
833                     case am_I:
834                         insn_to_complete->appendOperand(decodeImmediate(optype, b.start + 
835                                                                         locs->imm_position[imm_index++]), 
836                                                         isRead, isWritten);
837                         break;
838                     case am_J:
839                     {
840                         Expression::Ptr Offset(decodeImmediate(optype, 
841                                                                b.start + locs->imm_position[imm_index++], 
842                                                                true));
843                         Expression::Ptr EIP(makeRegisterExpression(MachRegister::getPC(m_Arch)));
844                         Expression::Ptr InsnSize(make_shared(singleton_object_pool<Immediate>::construct(Result(u8,
845                             decodedInstruction->getSize()))));
846                         Expression::Ptr postEIP(makeAddExpression(EIP, InsnSize, u32));
847
848                         Expression::Ptr op(makeAddExpression(Offset, postEIP, u32));
849                         insn_to_complete->addSuccessor(op, isCall, false, isConditional, false);
850                         if (isConditional) 
851                           insn_to_complete->addSuccessor(postEIP, false, false, true, true);
852                     }
853                     break;
854                     case am_O:
855                     {
856                     // Address/offset width, which is *not* what's encoded by the optype...
857                     // The deref's width is what's actually encoded here.
858                         int pseudoOpType;
859                         switch(locs->address_size)
860                         {
861                             case 1:
862                                 pseudoOpType = op_b;
863                                 break;
864                             case 2:
865                                 pseudoOpType = op_w;
866                                 break;
867                             case 4:
868                                 pseudoOpType = op_d;
869                                 break;
870                             case 0:
871                                 // closest I can get to "will be address size by default"
872                                 pseudoOpType = op_v;
873                                 break;
874                             default:
875                                 assert(!"Bad address size, should be 0, 1, 2, or 4!");
876                                 pseudoOpType = op_b;
877                                 break;
878                         }
879
880
881                         int offset_position = locs->opcode_position;
882                         if(locs->modrm_position > offset_position && locs->modrm_operand <
883                            (int)(insn_to_complete->m_Operands.size()))
884                         {
885                             offset_position = locs->modrm_position;
886                         }
887                         if(locs->sib_position > offset_position)
888                         {
889                             offset_position = locs->sib_position;
890                         }
891                         offset_position++;
892                         insn_to_complete->appendOperand(makeDereferenceExpression(
893                                 decodeImmediate(pseudoOpType, b.start + offset_position), makeSizeType(optype)), 
894                                                         isRead, isWritten);
895                     }
896                     break;
897                     case am_P:
898                         insn_to_complete->appendOperand(makeRegisterExpression(IntelRegTable(m_Arch,b_mm,locs->modrm_reg)),
899                                 isRead, isWritten);
900                         break;
901                     case am_Q:
902         
903                         switch(locs->modrm_mod)
904                         {
905                             // direct dereference
906                             case 0x00:
907                             case 0x01:
908                             case 0x02:
909                               insn_to_complete->appendOperand(makeModRMExpression(b, optype), isRead, isWritten);
910                                 break;
911                             case 0x03:
912                                 // use of actual register
913                                 insn_to_complete->appendOperand(makeRegisterExpression(IntelRegTable(m_Arch,b_mm,locs->modrm_rm)),
914                                                                isRead, isWritten);
915                                 break;
916                             default:
917                                 assert(!"2-bit value modrm_mod out of range");
918                                 break;
919                         };
920                         break;
921                     case am_S:
922                     // Segment register in modrm reg field.
923                         insn_to_complete->appendOperand(makeRegisterExpression(IntelRegTable(m_Arch,b_segment,locs->modrm_reg)),
924                                 isRead, isWritten);
925                         break;
926                     case am_T:
927                         // test register in modrm reg; should only be tr6/tr7, but we'll decode any of them
928                         // NOTE: this only appears in deprecated opcodes
929                         insn_to_complete->appendOperand(makeRegisterExpression(IntelRegTable(m_Arch,b_tr,locs->modrm_reg)),
930                                                        isRead, isWritten);
931                         break;
932                     case am_UM:
933                         switch(locs->modrm_mod)
934                         {
935                         // direct dereference
936                         case 0x00:
937                         case 0x01:
938                         case 0x02:
939                                 insn_to_complete->appendOperand(makeModRMExpression(b, makeSizeType(optype)),
940                                                 isRead, isWritten);
941                                 break;
942                         case 0x03:
943                                 // use of actual register
944                                 {
945                                         insn_to_complete->appendOperand(makeRegisterExpression(IntelRegTable(m_Arch,
946                                                         (locs->rex_b == 1) ? b_xmmhigh : b_xmm, locs->modrm_rm)),
947                                                         isRead, isWritten);
948                                         break;
949                                 }
950                         default:
951                                 assert(!"2-bit value modrm_mod out of range");
952                                 break;
953                         };
954                         break;
955                     case am_V:
956                        
957                         insn_to_complete->appendOperand(makeRegisterExpression(IntelRegTable(m_Arch,
958                                 (locs->rex_r == 1 )? b_xmmhigh : b_xmm,locs->modrm_reg)),
959                                     isRead, isWritten);
960                         break;
961                     case am_W:
962                         switch(locs->modrm_mod)
963                         {
964                             // direct dereference
965                             case 0x00:
966                             case 0x01:
967                             case 0x02:
968                               insn_to_complete->appendOperand(makeModRMExpression(b, makeSizeType(optype)),
969                                                                isRead, isWritten);
970                                 break;
971                             case 0x03:
972                             // use of actual register
973                             {
974                                 insn_to_complete->appendOperand(makeRegisterExpression(IntelRegTable(m_Arch,
975                                         (locs->rex_b == 1) ? b_xmmhigh : b_xmm, locs->modrm_rm)),
976                                         isRead, isWritten);
977                                 break;
978                             }
979                             default:
980                                 assert(!"2-bit value modrm_mod out of range");
981                                 break;
982                         };
983                         break;
984                     case am_X:
985                     {
986                         MachRegister si_reg;
987                         if(m_Arch == Arch_x86)
988                         {
989                                 if(addrSizePrefixPresent)
990                                 {
991                                         si_reg = x86::si;
992                                 } else
993                                 {
994                                         si_reg = x86::esi;
995                                 }
996                         }
997                         else
998                         {
999                                 if(addrSizePrefixPresent)
1000                                 {
1001                                         si_reg = x86_64::esi;
1002                                 } else
1003                                 {
1004                                         si_reg = x86_64::rsi;
1005                                 }
1006                         }
1007                         Expression::Ptr ds(makeRegisterExpression(m_Arch == Arch_x86 ? x86::ds : x86_64::ds));
1008                         Expression::Ptr si(makeRegisterExpression(si_reg));
1009                         Expression::Ptr segmentOffset(make_shared(singleton_object_pool<Immediate>::construct(
1010                                 Result(u32, 0x10))));
1011                         Expression::Ptr ds_segment = makeMultiplyExpression(ds, segmentOffset, u32);
1012                         Expression::Ptr ds_si = makeAddExpression(ds_segment, si, u32);
1013                         insn_to_complete->appendOperand(makeDereferenceExpression(ds_si, makeSizeType(optype)),
1014                                                        isRead, isWritten);
1015                     }
1016                     break;
1017                     case am_Y:
1018                     {
1019                         MachRegister di_reg;
1020                         if(m_Arch == Arch_x86)
1021                         {
1022                                 if(addrSizePrefixPresent)
1023                                 {
1024                                         di_reg = x86::di;
1025                                 } else
1026                                 {
1027                                         di_reg = x86::edi;
1028                                 }
1029                         }
1030                         else
1031                         {
1032                                 if(addrSizePrefixPresent)
1033                                 {
1034                                         di_reg = x86_64::edi;
1035                                 } else
1036                                 {
1037                                         di_reg = x86_64::rdi;
1038                                 }
1039                         }
1040                         Expression::Ptr es(makeRegisterExpression(m_Arch == Arch_x86 ? x86::es : x86_64::es));
1041                         Expression::Ptr di(makeRegisterExpression(di_reg));
1042                         Expression::Ptr es_segment = makeMultiplyExpression(es,
1043                             make_shared(singleton_object_pool<Immediate>::construct(Result(u32, 0x10))), u32);
1044                         Expression::Ptr es_di = makeAddExpression(es_segment, di, u32);
1045                         insn_to_complete->appendOperand(makeDereferenceExpression(es_di, makeSizeType(optype)),
1046                                                        isRead, isWritten);
1047                     }
1048                     break;
1049                     case am_tworeghack:
1050                     {
1051                         if(optype == op_edxeax)
1052                         {
1053                             Expression::Ptr edx(makeRegisterExpression(m_Arch == Arch_x86 ? x86::edx : x86_64::edx));
1054                             Expression::Ptr eax(makeRegisterExpression(m_Arch == Arch_x86 ? x86::eax : x86_64::eax));
1055                             Expression::Ptr highAddr = makeMultiplyExpression(edx,
1056                                     Immediate::makeImmediate(Result(u64, 2^32)), u64);
1057                             Expression::Ptr addr = makeAddExpression(highAddr, eax, u64);
1058                             Expression::Ptr op = makeDereferenceExpression(addr, u64);
1059                             insn_to_complete->appendOperand(op, isRead, isWritten);
1060                         }
1061                         else if (optype == op_ecxebx)
1062                         {
1063                             Expression::Ptr ecx(makeRegisterExpression(m_Arch == Arch_x86 ? x86::ecx : x86_64::ecx));
1064                             Expression::Ptr ebx(makeRegisterExpression(m_Arch == Arch_x86 ? x86::ebx : x86_64::ebx));
1065                             Expression::Ptr highAddr = makeMultiplyExpression(ecx,
1066                                     Immediate::makeImmediate(Result(u64, 2^32)), u64);
1067                             Expression::Ptr addr = makeAddExpression(highAddr, ebx, u64);
1068                             Expression::Ptr op = makeDereferenceExpression(addr, u64);
1069                             insn_to_complete->appendOperand(op, isRead, isWritten);
1070                         }
1071                     }
1072                     break;
1073                     
1074                     case am_reg:
1075                     {
1076                         MachRegister r(optype);
1077                         r = MachRegister((r.val() & ~r.getArchitecture()) | m_Arch);
1078                         entryID entryid = decodedInstruction->getEntry()->getID(locs);
1079                         if(locs->rex_b && insn_to_complete->m_Operands.empty() && 
1080                             (entryid == e_push || entryid == e_pop || entryid == e_xchg || ((*(b.start + locs->opcode_position) & 0xf0) == 0xb0) ) )
1081                         {
1082                             // FP stack registers are not affected by the rex_b bit in AM_REG.
1083                            if(r.regClass() != (unsigned) x86::MMX)
1084                             {
1085                                 r = MachRegister((r.val()) | x86_64::r8.val());
1086                             }
1087                         }
1088                         if(sizePrefixPresent)
1089                         {
1090                             r = MachRegister((r.val() & ~x86::FULL) | x86::W_REG);
1091                         }
1092                         Expression::Ptr op(makeRegisterExpression(r));
1093                         insn_to_complete->appendOperand(op, isRead, isWritten);
1094                     }
1095                     break;
1096                 case am_stackH:
1097                 case am_stackP:
1098                 // handled elsewhere
1099                     break;
1100                 case am_allgprs:
1101                 {
1102                     if(m_Arch == Arch_x86)
1103                     {
1104                         insn_to_complete->appendOperand(makeRegisterExpression(x86::eax), isRead, isWritten);
1105                         insn_to_complete->appendOperand(makeRegisterExpression(x86::ecx), isRead, isWritten);
1106                         insn_to_complete->appendOperand(makeRegisterExpression(x86::edx), isRead, isWritten);
1107                         insn_to_complete->appendOperand(makeRegisterExpression(x86::ebx), isRead, isWritten);
1108                         insn_to_complete->appendOperand(makeRegisterExpression(x86::esp), isRead, isWritten);
1109                         insn_to_complete->appendOperand(makeRegisterExpression(x86::ebp), isRead, isWritten);
1110                         insn_to_complete->appendOperand(makeRegisterExpression(x86::esi), isRead, isWritten);
1111                         insn_to_complete->appendOperand(makeRegisterExpression(x86::edi), isRead, isWritten);
1112                     }
1113                     else
1114                     {
1115                         insn_to_complete->appendOperand(makeRegisterExpression(x86_64::eax), isRead, isWritten);
1116                         insn_to_complete->appendOperand(makeRegisterExpression(x86_64::ecx), isRead, isWritten);
1117                         insn_to_complete->appendOperand(makeRegisterExpression(x86_64::edx), isRead, isWritten);
1118                         insn_to_complete->appendOperand(makeRegisterExpression(x86_64::ebx), isRead, isWritten);
1119                         insn_to_complete->appendOperand(makeRegisterExpression(x86_64::esp), isRead, isWritten);
1120                         insn_to_complete->appendOperand(makeRegisterExpression(x86_64::ebp), isRead, isWritten);
1121                         insn_to_complete->appendOperand(makeRegisterExpression(x86_64::esi), isRead, isWritten);
1122                         insn_to_complete->appendOperand(makeRegisterExpression(x86_64::edi), isRead, isWritten);
1123                     }
1124                 }
1125                     break;
1126                 case am_ImplImm: {
1127                   insn_to_complete->appendOperand(Immediate::makeImmediate(Result(makeSizeType(optype), 1)), isRead, isWritten);
1128                   break;
1129                 }
1130
1131                 default:
1132                     printf("decodeOneOperand() called with unknown addressing method %d\n", operand.admet);
1133                         break;
1134                 };
1135                 return true;
1136             }
1137
1138     extern ia32_entry invalid;
1139     
1140     void InstructionDecoder_x86::doIA32Decode(InstructionDecoder::buffer& b)
1141     {
1142         if(decodedInstruction == NULL)
1143         {
1144             decodedInstruction = reinterpret_cast<ia32_instruction*>(malloc(sizeof(ia32_instruction)));
1145             assert(decodedInstruction);
1146         }
1147         if(locs == NULL)
1148         {
1149             locs = reinterpret_cast<ia32_locations*>(malloc(sizeof(ia32_locations)));
1150             assert(locs);
1151         }
1152         locs = new(locs) ia32_locations; //reinit();
1153         assert(locs->sib_position == -1);
1154         decodedInstruction = new (decodedInstruction) ia32_instruction(NULL, NULL, locs);
1155         ia32_decode(IA32_DECODE_PREFIXES, b.start, *decodedInstruction);
1156         sizePrefixPresent = (decodedInstruction->getPrefix()->getOperSzPrefix() == 0x66);
1157         if (decodedInstruction->getPrefix()->rexW()) {
1158            // as per 2.2.1.2 - rex.w overrides 66h
1159            sizePrefixPresent = false;
1160         }
1161         addrSizePrefixPresent = (decodedInstruction->getPrefix()->getAddrSzPrefix() == 0x67);
1162     }
1163     
1164     void InstructionDecoder_x86::decodeOpcode(InstructionDecoder::buffer& b)
1165     {
1166         static ia32_entry invalid = { e_No_Entry, 0, 0, true, { {0,0}, {0,0}, {0,0} }, 0, 0 };
1167         doIA32Decode(b);
1168         if(decodedInstruction->getEntry()) {
1169             m_Operation = make_shared(singleton_object_pool<Operation>::construct(decodedInstruction->getEntry(),
1170                                     decodedInstruction->getPrefix(), locs, m_Arch));
1171             
1172         }
1173         else
1174         {
1175                 // Gap parsing can trigger this case; in particular, when it encounters prefixes in an invalid order.
1176                 // Notably, if a REX prefix (0x40-0x48) appears followed by another prefix (0x66, 0x67, etc)
1177                 // we'll reject the instruction as invalid and send it back with no entry.  Since this is a common
1178                 // byte sequence to see in, for example, ASCII strings, we want to simply accept this and move on, not
1179                 // yell at the user.
1180             m_Operation = make_shared(singleton_object_pool<Operation>::construct(&invalid,
1181                                     decodedInstruction->getPrefix(), locs, m_Arch));
1182         }
1183         b.start += decodedInstruction->getSize();
1184     }
1185     
1186       bool InstructionDecoder_x86::decodeOperands(const Instruction* insn_to_complete)
1187     {
1188        int imm_index = 0; // handle multiple immediate operands
1189         if(!decodedInstruction) return false;
1190         unsigned int opsema = decodedInstruction->getEntry()->opsema & 0xFF;
1191         InstructionDecoder::buffer b(insn_to_complete->ptr(), insn_to_complete->size());
1192
1193         if (decodedInstruction->getEntry()->getID() == e_ret_near ||
1194             decodedInstruction->getEntry()->getID() == e_ret_far) {
1195            Expression::Ptr ret_addr = makeDereferenceExpression(makeRegisterExpression(ia32_is_mode_64() ? x86_64::rsp : x86::esp), 
1196                                                                 ia32_is_mode_64() ? u64 : u32);
1197            insn_to_complete->addSuccessor(ret_addr, false, true, false, false);
1198         }
1199
1200         for(unsigned i = 0; i < 3; i++)
1201         {
1202             if(decodedInstruction->getEntry()->operands[i].admet == 0 && 
1203                decodedInstruction->getEntry()->operands[i].optype == 0)
1204                 return true;
1205             if(!decodeOneOperand(b,
1206                                  decodedInstruction->getEntry()->operands[i], 
1207                                  imm_index, 
1208                                  insn_to_complete, 
1209                                  readsOperand(opsema, i),
1210                                  writesOperand(opsema, i)))
1211             {
1212                 return false;
1213             }
1214         }
1215     
1216         return true;
1217     }
1218
1219     
1220       INSTRUCTION_EXPORT Instruction::Ptr InstructionDecoder_x86::decode(InstructionDecoder::buffer& b)
1221     {
1222         return InstructionDecoderImpl::decode(b);
1223     }
1224     void InstructionDecoder_x86::doDelayedDecode(const Instruction* insn_to_complete)
1225     {
1226       InstructionDecoder::buffer b(insn_to_complete->ptr(), insn_to_complete->size());
1227       //insn_to_complete->m_Operands.reserve(4);
1228       doIA32Decode(b);        
1229       decodeOperands(insn_to_complete);
1230     }
1231     
1232 };
1233 };
1234