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