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