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