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