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