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