Palacios Public Git Repository

To checkout Palacios execute

  git clone http://v3vee.org/palacios/palacios.web/palacios.git
This will give you the master branch. You probably want the devel branch or one of the release branches. To switch to the devel branch, simply execute
  cd palacios
  git checkout --track -b devel origin/devel
The other branches are similar.


added checks for 64 bit operand decoding
[palacios.git] / palacios / include / palacios / vmm_instr_decoder.h
1 /*
2  * This file is part of the Palacios Virtual Machine Monitor developed
3  * by the V3VEE Project with funding from the United States National 
4  * Science Foundation and the Department of Energy.  
5  *
6  * The V3VEE Project is a joint project between Northwestern University
7  * and the University of New Mexico.  You can find out more at 
8  * http://www.v3vee.org
9  *
10  * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu> 
11  * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org> 
12  * All rights reserved.
13  *
14  * Author: Jack Lange <jarusl@cs.northwestern.edu>
15  *
16  * This is free software.  You are permitted to use,
17  * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
18  */
19
20 #include <palacios/vmm_types.h>
21
22
23 /* .... Giant fucking switch tables */
24
25
26 typedef enum {
27     INVALID_INSTR,
28     LMSW,
29     SMSW,
30     CLTS,
31     INVLPG,
32
33     MOV_CR2,
34     MOV_2CR,
35     MOV_DR2,
36     MOV_2DR,
37     MOV_SR2,
38     MOV_2SR,
39
40     MOV_MEM2_8,
41     MOV_MEM2,
42     MOV_2MEM_8,
43     MOV_2MEM,
44     MOV_MEM2AL_8,
45     MOV_MEM2AX,
46     MOV_AL2MEM_8,
47     MOV_AX2MEM,
48     MOV_IMM2_8,
49     MOV_IMM2,
50
51     MOVS_8,
52     MOVS,
53     MOVSX_8,
54     MOVSX,
55     MOVZX_8,
56     MOVZX,
57
58     HLT,
59     PUSHF,
60     POPF,
61
62     ADC_2MEM_8,
63     ADC_2MEM,
64     ADC_MEM2_8,
65     ADC_MEM2,
66     ADC_IMM2_8,
67     ADC_IMM2,
68     ADC_IMM2SX_8,
69     ADD_IMM2_8,
70     ADD_IMM2,
71     ADD_IMM2SX_8,
72     ADD_2MEM_8,
73     ADD_2MEM,
74     ADD_MEM2_8,
75     ADD_MEM2,
76     AND_MEM2_8,
77     AND_MEM2,
78     AND_2MEM_8,
79     AND_2MEM,
80     AND_IMM2_8,
81     AND_IMM2,
82     AND_IMM2SX_8,
83     OR_2MEM_8,
84     OR_2MEM,
85     OR_MEM2_8,
86     OR_MEM2,
87     OR_IMM2_8,
88     OR_IMM2,
89     OR_IMM2SX_8,
90     SUB_2MEM_8,
91     SUB_2MEM,
92     SUB_MEM2_8,
93     SUB_MEM2,
94     SUB_IMM2_8,
95     SUB_IMM2,
96     SUB_IMM2SX_8,
97     XOR_2MEM_8,
98     XOR_2MEM,
99     XOR_MEM2_8,
100     XOR_MEM2,
101     XOR_IMM2_8,
102     XOR_IMM2,
103     XOR_IMM2SX_8,
104
105     INC_8,
106     INC,
107     DEC_8,
108     DEC,
109     NEG_8,
110     NEG, 
111     NOT_8,
112     NOT,
113     XCHG_8,
114     XCHG,
115
116     SETB,
117     SETBE,
118     SETL,
119     SETLE,
120     SETNB,
121     SETNBE,
122     SETNL,
123     SETNLE,
124     SETNO,
125     SETNP,
126     SETNS,
127     SETNZ,
128     SETP,
129     SETS,
130     SETZ,
131     SETO,
132
133     STOS_8,
134     STOS
135 } op_form_t;
136
137
138 static int get_addr_width(struct guest_info * info, struct x86_instr * instr) {
139
140     switch (v3_get_vm_cpu_mode(info)) {
141         case REAL:
142             return (instr->prefixes.addr_size) ? 4 : 2;
143         case LONG:
144                 return 8;
145         case PROTECTED:
146         case PROTECTED_PAE:
147         case LONG_32_COMPAT:
148                 if (info->segments.cs.db) {
149                         return (instr->prefixes.addr_size) ? 2 : 4;
150                 } else {
151                         return (instr->prefixes.addr_size) ? 4 : 2;
152                 }                       
153         default:
154             PrintError("Unsupported CPU mode: %d\n", info->cpu_mode);
155             return -1;
156     }
157 }
158
159 static int get_operand_width(struct guest_info * info, struct x86_instr * instr, 
160                              op_form_t form) {
161     switch (form) {
162
163         case CLTS:
164         case HLT:
165             return 0;
166
167         case MOV_MEM2_8:
168         case MOV_2MEM_8:
169         case MOV_MEM2AL_8:
170         case MOV_AL2MEM_8:
171         case MOV_IMM2_8:
172         case MOVS_8:
173         case MOVSX_8:
174         case MOVZX_8:
175         case ADC_2MEM_8:
176         case ADC_MEM2_8:
177         case ADC_IMM2_8:
178         case ADD_IMM2_8:
179         case ADD_2MEM_8:
180         case ADD_MEM2_8:
181         case AND_MEM2_8:
182         case AND_2MEM_8:
183         case AND_IMM2_8:
184         case OR_2MEM_8:
185         case OR_MEM2_8:
186         case OR_IMM2_8:
187         case SUB_2MEM_8:
188         case XOR_2MEM_8:
189         case SUB_MEM2_8:
190         case SUB_IMM2_8:
191         case XOR_MEM2_8:
192         case XOR_IMM2_8:
193         case INC_8:
194         case DEC_8:
195         case NEG_8:
196         case NOT_8:
197         case XCHG_8:
198         case STOS_8:
199         case SETB:
200         case SETBE:
201         case SETL:
202         case SETLE:
203         case SETNB:
204         case SETNBE:
205         case SETNL:
206         case SETNLE:
207         case SETNO:
208         case SETNP:
209         case SETNS:
210         case SETNZ:
211         case SETP:
212         case SETS:
213         case SETZ:
214         case SETO:
215             return 1;
216
217         case LMSW:
218         case SMSW:
219             return 2;
220
221         case MOV_MEM2:
222         case MOV_2MEM:
223         case MOV_MEM2AX:
224         case MOV_AX2MEM:
225         case MOV_IMM2:      
226         case MOVS:
227         case MOVSX:
228         case MOVZX:
229         case ADC_2MEM:
230         case ADC_MEM2:
231         case ADC_IMM2:
232         case ADD_IMM2:
233         case ADD_2MEM:
234         case ADD_MEM2:
235         case AND_MEM2:
236         case AND_2MEM:
237         case AND_IMM2:
238         case OR_2MEM:
239         case OR_MEM2:
240         case OR_IMM2:
241         case SUB_2MEM:
242         case SUB_MEM2:
243         case SUB_IMM2:
244         case XOR_2MEM:
245         case XOR_MEM2:
246         case XOR_IMM2:
247         case INC:
248         case DEC:
249         case NEG: 
250         case NOT:
251         case STOS:
252         case XCHG:
253         case ADC_IMM2SX_8:
254         case AND_IMM2SX_8:
255         case ADD_IMM2SX_8:
256         case OR_IMM2SX_8:
257         case SUB_IMM2SX_8:
258         case XOR_IMM2SX_8:
259             switch (v3_get_vm_cpu_mode(info)) {
260                 case REAL:
261                     return (instr->prefixes.op_size) ? 4 : 2;
262                 case LONG:
263                     if (instr->prefixes.rex.op_size) {
264                         return 8;
265                     }
266                 case PROTECTED:
267                 case PROTECTED_PAE:
268                 case LONG_32_COMPAT:
269                     if (info->segments.cs.db) {
270                         // default is 32
271                         return (instr->prefixes.op_size) ? 2 : 4;
272                     } else {
273                         return (instr->prefixes.op_size) ? 4 : 2;
274                     }
275                 default:
276                     PrintError("Unsupported CPU mode: %d\n", info->cpu_mode);
277                     return -1;
278             }
279             
280         case INVLPG:
281             switch (v3_get_vm_cpu_mode(info)) {
282                 case REAL:
283                     PrintError("Invalid instruction given operating mode (%d)\n", form);
284                     return 0;
285                 case PROTECTED:
286                 case PROTECTED_PAE:
287                 case LONG_32_COMPAT:
288                         return 4;
289                 case LONG:
290                         return 8;
291                 default:
292                     PrintError("Unsupported CPU mode: %d\n", info->cpu_mode);
293                     return -1;
294             }
295
296         case PUSHF:
297         case POPF:
298             switch (v3_get_vm_cpu_mode(info)) {
299                 case REAL:
300                     return 2;
301                 case PROTECTED:
302                 case PROTECTED_PAE:
303                 case LONG_32_COMPAT:
304                         return 4;
305                 case LONG:
306                         return 8;
307                 default:
308                     PrintError("Unsupported CPU mode: %d\n", info->cpu_mode);
309                     return -1;
310             }
311
312         case MOV_DR2:
313         case MOV_2DR:
314         case MOV_CR2:
315         case MOV_2CR:
316             switch (v3_get_vm_cpu_mode(info)) {
317                 case REAL:
318                 case PROTECTED:
319                 case PROTECTED_PAE:
320                 case LONG_32_COMPAT:
321
322                         return 4;
323                 case LONG:
324                         return 8;
325                 default:
326                     PrintError("Unsupported CPU mode: %d\n", info->cpu_mode);
327                     return -1;
328             }
329
330         case MOV_SR2:
331         case MOV_2SR:
332         default:
333             PrintError("Unsupported instruction form %d\n", form);
334             return -1;
335         
336     }
337     return 0;
338 }
339
340
341
342 typedef enum {INVALID_ADDR_TYPE, REG, DISP0, DISP8, DISP16, DISP32} modrm_mode_t;
343 typedef enum {INVALID_REG_SIZE, REG64, REG32, REG16, REG8} reg_size_t;
344
345
346 struct modrm_byte {
347     uint_t rm   :   3;
348     uint_t reg  :   3;
349     uint_t mod  :   2;
350 } __attribute__((packed));
351
352
353 struct sib_byte {
354     uint_t base     :   3;
355     uint_t index    :   3;
356     uint_t scale    :   2;
357 } __attribute__((packed));
358
359
360
361
362 struct v3_gprs;
363
364 static inline int decode_gpr(struct guest_info * core,
365                              uint8_t reg_code,
366                              struct x86_operand * reg) {
367
368     struct v3_gprs * gprs = &(core->vm_regs);
369
370     switch (reg_code) {
371         case 0:
372             reg->operand = (addr_t)&(gprs->rax);
373             break;
374         case 1:
375             reg->operand = (addr_t)&(gprs->rcx);
376             break;
377         case 2:
378             reg->operand = (addr_t)&(gprs->rdx);
379             break;
380         case 3:
381             reg->operand = (addr_t)&(gprs->rbx);
382             break;
383         case 4:
384             if (reg->size == 1) {
385                 reg->operand = (addr_t)&(gprs->rax) + 1;
386             } else {
387                 reg->operand = (addr_t)&(gprs->rsp);
388             }
389             break;
390         case 5:
391             if (reg->size == 1) {
392                 reg->operand = (addr_t)&(gprs->rcx) + 1;
393             } else {
394                 reg->operand = (addr_t)&(gprs->rbp);
395             }
396             break;
397         case 6:
398             if (reg->size == 1) {
399                 reg->operand = (addr_t)&(gprs->rdx) + 1;
400             } else {
401                 reg->operand = (addr_t)&(gprs->rsi);
402             }
403             break;
404         case 7:
405             if (reg->size == 1) {
406                 reg->operand = (addr_t)&(gprs->rbx) + 1;
407             } else {
408                 reg->operand = (addr_t)&(gprs->rdi);
409             }
410             break;
411         default:
412             PrintError("Invalid Reg Code (%d)\n", reg_code);
413             reg->operand = 0;
414             return -1;
415     }
416
417     return 0;
418 }
419
420
421
422
423 static inline int decode_cr(struct guest_info * core,                   
424                              uint8_t reg_code,
425                              struct x86_operand * reg) {
426
427     struct v3_ctrl_regs * crs = &(core->ctrl_regs);
428
429     PrintDebug("\t Ctrl regs %d\n", reg_code);
430
431     switch (reg_code) {
432         case 0:
433             reg->operand = (addr_t)&(crs->cr0);
434             break;
435         case 2:
436             reg->operand = (addr_t)&(crs->cr2);
437             break;
438         case 3:
439             reg->operand = (addr_t)&(crs->cr3);
440             break;
441         case 4:
442             reg->operand = (addr_t)&(crs->cr4);
443             break;
444         default:
445             reg->operand = 0;
446             PrintError("Invalid Reg Code (%d)\n", reg_code);
447             return -1;
448     }
449
450     return 0;
451 }
452
453 // This converts the displacement into the appropriate masked value
454 /* 
455    QUESTION: Are the register Values signed ?????
456  */
457 #define MASK_DISPLACEMENT(reg, mode) ({                                 \
458             sint64_t val = 0;                                           \
459             if (mode == DISP8) {                                        \
460                 val = (sint8_t)(reg & 0xff);                            \
461             } else if (mode == DISP16) {                                \
462                 val = (sint16_t)(reg & 0xffff);                         \
463             } else if (mode == DISP32) {                                \
464                 val = (sint32_t)(reg & 0xffffffff);                     \
465             } else {                                                    \
466                 PrintError("Error invalid displacement size (%d)\n", mode); \
467                 /*V3_ASSERT(0);*/                                       \
468             }                                                           \
469             val;                                                        \
470         })
471
472
473 #define ADDR_MASK(val, length) ({                             \
474             ullong_t mask = 0x0LL;                            \
475             switch (length) {                                 \
476                 case 2:                                       \
477                     mask = 0x00000000000fffffLL;              \
478                     break;                                    \
479                 case 4:                                       \
480                     mask = 0x00000000ffffffffLL;              \
481                     break;                                    \
482                 case 8:                                       \
483                     mask = 0xffffffffffffffffLL;              \
484                     break;                                    \
485             }                                                 \
486             val & mask;                                       \
487         })
488
489
490
491 static  int decode_rm_operand16(struct guest_info * core,
492                                 uint8_t * modrm_instr, 
493                                 struct x86_instr * instr,
494                                 struct x86_operand * operand, 
495                                 uint8_t * reg_code) { 
496
497     struct v3_gprs * gprs = &(core->vm_regs);
498     struct modrm_byte * modrm = (struct modrm_byte *)modrm_instr;
499     addr_t base_addr = 0;
500     modrm_mode_t mod_mode = 0;
501     uint8_t * instr_cursor = modrm_instr;
502
503     //  PrintDebug("ModRM mod=%d\n", modrm->mod);
504     
505     *reg_code = modrm->reg;
506
507     instr_cursor += 1;
508
509     if (modrm->mod == 3) {
510         //PrintDebug("first operand = Register (RM=%d)\n",modrm->rm);
511         operand->type = REG_OPERAND;
512
513         decode_gpr(core, modrm->rm, operand);
514
515     } else {
516         struct v3_segment * seg = NULL;
517
518         operand->type = MEM_OPERAND;
519
520         if (modrm->mod == 0) {
521             mod_mode = DISP0;
522         } else if (modrm->mod == 1) {
523             mod_mode = DISP8;
524         } else if (modrm->mod == 2) {
525             mod_mode = DISP16;
526         }
527
528         switch (modrm->rm) {
529             case 0:
530                 base_addr = gprs->rbx + MASK_DISPLACEMENT(gprs->rsi, mod_mode);
531                 break;
532             case 1:
533                 base_addr = gprs->rbx + MASK_DISPLACEMENT(gprs->rdi, mod_mode);
534                 break;
535             case 2:
536                 base_addr = gprs->rbp + MASK_DISPLACEMENT(gprs->rsi, mod_mode);
537                 break;
538             case 3:
539                 base_addr = gprs->rbp + MASK_DISPLACEMENT(gprs->rdi, mod_mode);
540                 break;
541             case 4:
542                 base_addr = gprs->rsi;
543                 break;
544             case 5:
545                 base_addr = gprs->rdi;
546                 break;
547             case 6:
548                 if (modrm->mod == 0) {
549                     base_addr = 0;
550                     mod_mode = DISP16;
551                 } else {
552                     base_addr = gprs->rbp;
553                 }
554                 break;
555             case 7:
556                 base_addr = gprs->rbx;
557                 break;
558         }
559
560
561
562         if (mod_mode == DISP8) {
563             base_addr += *(sint8_t *)instr_cursor;
564             instr_cursor += 1;
565         } else if (mod_mode == DISP16) {
566             base_addr += *(sint16_t *)instr_cursor;
567             instr_cursor += 2;
568         }
569     
570         
571         // get appropriate segment
572         if (instr->prefixes.cs_override) {
573             seg = &(core->segments.cs);
574         } else if (instr->prefixes.es_override) {
575             seg = &(core->segments.es);
576         } else if (instr->prefixes.ss_override) {
577             seg = &(core->segments.ss);
578         } else if (instr->prefixes.fs_override) {
579             seg = &(core->segments.fs);
580         } else if (instr->prefixes.gs_override) {
581             seg = &(core->segments.gs);
582         } else {
583             seg = &(core->segments.ds);
584         }
585         
586         operand->operand = ADDR_MASK(get_addr_linear(core, base_addr, seg), 
587                                      get_addr_width(core, instr));
588     }
589
590
591     return (instr_cursor - modrm_instr);
592 }
593
594
595 // returns num_bytes parsed
596 static int decode_rm_operand32(struct guest_info * core, 
597                                uint8_t * modrm_instr,  
598                                struct x86_instr * instr,
599                                struct x86_operand * operand, 
600                                uint8_t * reg_code) {
601
602     struct v3_gprs * gprs = &(core->vm_regs);
603     uint8_t * instr_cursor = modrm_instr;
604     struct modrm_byte * modrm = (struct modrm_byte *)modrm_instr;
605     addr_t base_addr = 0;
606     modrm_mode_t mod_mode = 0;
607     uint_t has_sib_byte = 0;
608
609
610     *reg_code = modrm->reg;
611
612     instr_cursor += 1;
613
614     if (modrm->mod == 3) {
615         operand->type = REG_OPERAND;
616         //    PrintDebug("first operand = Register (RM=%d)\n",modrm->rm);
617
618         decode_gpr(core, modrm->rm, operand);
619
620     } else {
621         struct v3_segment * seg = NULL;
622
623         operand->type = MEM_OPERAND;
624
625         if (modrm->mod == 0) {
626             mod_mode = DISP0;
627         } else if (modrm->mod == 1) {
628             mod_mode = DISP8;
629         } else if (modrm->mod == 2) {
630             mod_mode = DISP32;
631         }
632     
633         switch (modrm->rm) {
634             case 0:
635                 base_addr = gprs->rax;
636                 break;
637             case 1:
638                 base_addr = gprs->rcx;
639                 break;
640             case 2:
641                 base_addr = gprs->rdx;
642                 break;
643             case 3:
644                 base_addr = gprs->rbx;
645                 break;
646             case 4:
647                 has_sib_byte = 1;
648                 break;
649             case 5:
650                 if (modrm->mod == 0) {
651                     base_addr = 0;
652                     mod_mode = DISP32;
653                 } else {
654                     base_addr = gprs->rbp;
655                 }
656                 break;
657             case 6:
658                 base_addr = gprs->rsi;
659                 break;
660             case 7:
661                 base_addr = gprs->rdi;
662                 break;
663         }
664
665         if (has_sib_byte) {
666             instr_cursor += 1;
667             struct sib_byte * sib = (struct sib_byte *)(instr_cursor);
668             int scale = 0x1 << sib->scale;
669
670             instr_cursor += 1;
671
672             switch (sib->index) {
673                 case 0:
674                     base_addr = gprs->rax;
675                     break;
676                 case 1:
677                     base_addr = gprs->rcx;
678                     break;
679                 case 2:
680                     base_addr = gprs->rdx;
681                     break;
682                 case 3:
683                     base_addr = gprs->rbx;
684                     break;
685                 case 4:
686                     base_addr = 0;
687                     break;
688                 case 5:
689                     base_addr = gprs->rbp;
690                     break;
691                 case 6:
692                     base_addr = gprs->rsi;
693                     break;
694                 case 7:
695                     base_addr = gprs->rdi;
696                     break;
697             }
698
699             base_addr *= scale;
700
701
702             switch (sib->base) {
703                 case 0:
704                     base_addr += MASK_DISPLACEMENT(gprs->rax, mod_mode);
705                     break;
706                 case 1:
707                     base_addr += MASK_DISPLACEMENT(gprs->rcx, mod_mode);
708                     break;
709                 case 2:
710                     base_addr += MASK_DISPLACEMENT(gprs->rdx, mod_mode);
711                     break;
712                 case 3:
713                     base_addr += MASK_DISPLACEMENT(gprs->rbx, mod_mode);
714                     break;
715                 case 4:
716                     base_addr += MASK_DISPLACEMENT(gprs->rsp, mod_mode);
717                     break;
718                 case 5:
719                     if (modrm->mod != 0) {
720                         base_addr += MASK_DISPLACEMENT(gprs->rbp, mod_mode);
721                     }
722                     break;
723                 case 6:
724                     base_addr += MASK_DISPLACEMENT(gprs->rsi, mod_mode);
725                     break;
726                 case 7:
727                     base_addr += MASK_DISPLACEMENT(gprs->rdi, mod_mode);
728                     break;
729             }
730
731         } 
732
733
734         if (mod_mode == DISP8) {
735             base_addr += *(sint8_t *)instr_cursor;
736             instr_cursor += 1;
737         } else if (mod_mode == DISP32) {
738             base_addr += *(sint32_t *)instr_cursor;
739             instr_cursor += 4;
740         }
741     
742         // get appropriate segment
743         if (instr->prefixes.cs_override) {
744             seg = &(core->segments.cs);
745         } else if (instr->prefixes.es_override) {
746             seg = &(core->segments.es);
747         } else if (instr->prefixes.ss_override) {
748             seg = &(core->segments.ss);
749         } else if (instr->prefixes.fs_override) {
750             seg = &(core->segments.fs);
751         } else if (instr->prefixes.gs_override) {
752             seg = &(core->segments.gs);
753         } else {
754             seg = &(core->segments.ds);
755         }
756         
757         operand->operand = ADDR_MASK(get_addr_linear(core, base_addr, seg), 
758                                 get_addr_width(core, instr));
759     }
760
761
762     return (instr_cursor - modrm_instr);
763 }
764
765
766 int decode_rm_operand64(struct guest_info * core, uint8_t * instr_ptr, 
767                         struct x86_instr * instr, struct x86_operand * operand, 
768                         uint8_t * reg_code) {
769     
770     
771                                         
772     return 0;
773 }
774
775
776 static int decode_rm_operand(struct guest_info * core, 
777                              uint8_t * instr_ptr,        // input
778                              op_form_t form, 
779                              struct x86_instr * instr,
780                              struct x86_operand * operand, 
781                              uint8_t * reg_code) {
782     
783     v3_cpu_mode_t mode = v3_get_vm_cpu_mode(core);
784
785     operand->size = get_operand_width(core, instr, form);
786
787     switch (mode) {
788         case REAL:
789             return decode_rm_operand16(core, instr_ptr, instr, operand, reg_code);
790         case LONG:
791             if (instr->prefixes.rex.op_size) {
792                 return decode_rm_operand64(core, instr_ptr, instr, operand, reg_code);
793             }
794         case PROTECTED:
795         case PROTECTED_PAE:
796         case LONG_32_COMPAT:
797             return decode_rm_operand32(core, instr_ptr, instr, operand, reg_code);
798         default:
799             PrintError("Invalid CPU_MODE (%d)\n", mode);
800             return -1;
801     }
802 }
803                              
804
805
806 static inline op_form_t op_code_to_form_0f(uint8_t * instr, int * length) {
807     *length += 1;
808
809     switch (instr[1]) {
810         case 0x01: {
811             struct modrm_byte * modrm = (struct modrm_byte *)&(instr[2]);
812
813             switch (modrm->reg) {
814                 case 4:
815                     return SMSW;
816                 case 6:
817                     return LMSW;
818                 case 7:
819                     return INVLPG;
820                 default:
821                     return INVALID_INSTR;
822             }
823         }
824
825         case 0x06:
826             return CLTS;
827         case 0x20:
828             return MOV_CR2;
829         case 0x21:
830             return MOV_DR2;
831
832         case 0x22:
833             return MOV_2CR;
834         case 0x23:
835             return MOV_2DR;
836
837         case 0x90:
838             return SETO;
839         case 0x91:
840             return SETNO;
841         case 0x92:
842             return SETB;
843         case 0x93:
844             return SETNB;
845         case 0x94:
846             return SETZ;
847         case 0x95:
848             return SETNZ;
849         case 0x96:
850             return SETBE;
851         case 0x97:
852             return SETNBE;
853         case 0x98:
854             return SETS;
855         case 0x99:
856             return SETNS;
857         case 0x9a:
858             return SETP;
859         case 0x9b:
860             return SETNP;
861         case 0x9c:
862             return SETL;
863         case 0x9d:
864             return SETNL;
865         case 0x9e:
866             return SETLE;
867         case 0x9f:
868             return SETNLE;
869
870         case 0xb6:
871             return MOVZX_8;
872         case 0xb7:
873             return MOVZX;
874
875         case 0xbe:
876             return MOVSX_8;
877         case 0xbf:
878             return MOVSX;
879             
880
881         default:
882             return INVALID_INSTR;
883     }
884 }
885
886
887 static op_form_t op_code_to_form(uint8_t * instr, int * length) {
888     *length += 1;
889
890     switch (instr[0]) {
891         case 0x00:
892             return ADD_2MEM_8;
893         case 0x01:
894             return ADD_2MEM;
895         case 0x02:
896             return ADD_MEM2_8;
897         case 0x03:
898             return ADD_MEM2;
899
900         case 0x08:
901             return OR_2MEM_8;
902         case 0x09:
903             return OR_2MEM;
904         case 0x0a:
905             return OR_MEM2_8;
906         case 0x0b:
907             return OR_MEM2;
908
909
910         case 0x0f:
911             return op_code_to_form_0f(instr, length);
912
913         case 0x10:
914             return ADC_2MEM_8;
915         case 0x11:
916             return ADC_2MEM;
917         case 0x12:
918             return ADC_MEM2_8;
919         case 0x13:
920             return ADC_MEM2;
921
922         case 0x20:
923             return AND_2MEM_8; 
924         case 0x21:
925             return AND_2MEM;
926         case 0x22:
927             return AND_MEM2_8;
928         case 0x23:
929             return AND_MEM2;
930
931         case 0x28:
932             return SUB_2MEM_8;
933         case 0x29:
934             return SUB_2MEM;
935         case 0x2a:
936             return SUB_MEM2_8;
937         case 0x2b:
938             return SUB_MEM2;
939
940
941         case 0x30:
942             return XOR_2MEM_8;
943         case 0x31:
944             return XOR_2MEM;
945         case 0x32:
946             return XOR_MEM2_8;
947         case 0x33:
948             return XOR_MEM2;
949
950         case 0x80:{
951             struct modrm_byte * modrm = (struct modrm_byte *)&(instr[1]);
952
953             switch (modrm->reg) {
954                 case 0:
955                     return ADD_IMM2_8;
956                 case 1:
957                     return OR_IMM2_8;
958                 case 2:
959                     return ADC_IMM2_8;
960                 case 4:
961                     return AND_IMM2_8;
962                 case 5:
963                     return SUB_IMM2_8;
964                 case 6:
965                     return XOR_IMM2_8;
966                 default:
967                     return INVALID_INSTR;
968             }
969         }
970         case 0x81: {
971             struct modrm_byte * modrm = (struct modrm_byte *)&(instr[1]);
972             
973             switch (modrm->reg) {
974                 case 0:
975                     return ADD_IMM2;
976                 case 1:
977                     return OR_IMM2;
978                 case 2:
979                     return ADC_IMM2;
980                 case 4:
981                     return AND_IMM2;
982                 case 5:
983                     return SUB_IMM2;
984                 case 6:
985                     return XOR_IMM2;
986                 default:
987                     return INVALID_INSTR;
988             }
989         }
990         case 0x83: {
991             struct modrm_byte * modrm = (struct modrm_byte *)&(instr[1]);
992
993             switch (modrm->reg) {
994                 case 0:
995                     return ADD_IMM2SX_8;
996                 case 1:
997                     return OR_IMM2SX_8;
998                 case 2:
999                     return ADC_IMM2SX_8;
1000                 case 4:
1001                     return AND_IMM2SX_8;
1002                 case 5:
1003                     return SUB_IMM2SX_8;
1004                 case 6:
1005                     return XOR_IMM2SX_8;
1006                 default:
1007                     return INVALID_INSTR;
1008             }
1009         }
1010
1011         case 0x86:
1012             return XCHG_8;
1013         case 0x87:
1014             return XCHG;
1015         case 0x88:
1016             return MOV_2MEM_8;
1017         case 0x89:
1018             return MOV_2MEM;
1019         case 0x8a:
1020             return MOV_MEM2_8;
1021         case 0x8b:
1022             return MOV_MEM2;
1023             
1024         case 0x8c:
1025             return MOV_SR2;
1026         case 0x8e:
1027             return MOV_2SR;
1028
1029
1030         case 0x9c:
1031             return PUSHF;
1032         case 0x9d:
1033             return POPF;
1034
1035         case 0xa0:
1036             return MOV_MEM2AL_8;
1037         case 0xa1:
1038             return MOV_MEM2AX;
1039         case 0xa2:
1040             return MOV_AL2MEM_8;
1041         case 0xa3:
1042             return MOV_AX2MEM;
1043
1044         case 0xa4:
1045             return MOVS_8;
1046         case 0xa5:
1047             return MOVS;
1048
1049         case 0xaa:
1050             return STOS_8;
1051         case 0xab:
1052             return STOS;
1053
1054         case 0xc6:
1055             return MOV_IMM2_8;
1056         case 0xc7:
1057             return MOV_IMM2;
1058
1059         case 0xf4:
1060             return HLT;
1061
1062
1063         case 0xf6: {
1064             struct modrm_byte * modrm = (struct modrm_byte *)&(instr[1]);
1065
1066             switch (modrm->reg) {
1067                 case 2:
1068                     return NOT_8;
1069                 case 3:
1070                     return NEG_8;
1071                 default:
1072                     return INVALID_INSTR;
1073             }
1074         }
1075         case 0xf7: {
1076             struct modrm_byte * modrm = (struct modrm_byte *)&(instr[1]);
1077
1078             switch (modrm->reg) {
1079                 case 2:
1080                     return NOT;
1081                 case 3:
1082                     return NEG;
1083                 default:
1084                     return INVALID_INSTR;
1085             }
1086         }
1087             
1088
1089         case 0xfe: {
1090             struct modrm_byte * modrm = (struct modrm_byte *)&(instr[1]);
1091
1092             switch (modrm->reg) {
1093                 case 0:
1094                     return INC_8;
1095                 case 1:
1096                     return DEC_8;
1097                 default:
1098                     return INVALID_INSTR;
1099             }
1100         }
1101
1102         case 0xff: {
1103             struct modrm_byte * modrm = (struct modrm_byte *)&(instr[1]);
1104
1105             switch (modrm->reg) {
1106                 case 0:
1107                     return INC;
1108                 case 1:
1109                     return DEC;
1110                 default:
1111                     return INVALID_INSTR;
1112             }
1113         }
1114
1115         default:
1116             return INVALID_INSTR;
1117     }
1118 }
1119
1120
1121
1122 static char * op_form_to_str(op_form_t form) {
1123
1124     switch (form) {
1125         case LMSW: return "LMSW";
1126         case SMSW: return "SMSW";
1127         case CLTS: return "CLTS";
1128         case INVLPG: return "INVLPG";
1129         case MOV_CR2: return "MOV_CR2";
1130         case MOV_2CR: return "MOV_2CR";
1131         case MOV_DR2: return "MOV_DR2";
1132         case MOV_2DR: return "MOV_2DR";
1133         case MOV_SR2: return "MOV_SR2";
1134         case MOV_2SR: return "MOV_2SR";
1135         case MOV_MEM2_8: return "MOV_MEM2_8";
1136         case MOV_MEM2: return "MOV_MEM2";
1137         case MOV_2MEM_8: return "MOV_2MEM_8";
1138         case MOV_2MEM: return "MOV_2MEM";
1139         case MOV_MEM2AL_8: return "MOV_MEM2AL_8";
1140         case MOV_MEM2AX: return "MOV_MEM2AX";
1141         case MOV_AL2MEM_8: return "MOV_AL2MEM_8";
1142         case MOV_AX2MEM: return "MOV_AX2MEM";
1143         case MOV_IMM2_8: return "MOV_IMM2_8";
1144         case MOV_IMM2: return "MOV_IMM2";
1145         case MOVS_8: return "MOVS_8";
1146         case MOVS: return "MOVS";
1147         case MOVSX_8: return "MOVSX_8";
1148         case MOVSX: return "MOVSX";
1149         case MOVZX_8: return "MOVZX_8";
1150         case MOVZX: return "MOVZX";
1151         case HLT: return "HLT";
1152         case PUSHF: return "PUSHF";
1153         case POPF: return "POPF";
1154         case ADC_2MEM_8: return "ADC_2MEM_8";
1155         case ADC_2MEM: return "ADC_2MEM";
1156         case ADC_MEM2_8: return "ADC_MEM2_8";
1157         case ADC_MEM2: return "ADC_MEM2";
1158         case ADC_IMM2_8: return "ADC_IMM2_8";
1159         case ADC_IMM2: return "ADC_IMM2";
1160         case ADC_IMM2SX_8: return "ADC_IMM2SX_8";
1161         case ADD_IMM2_8: return "ADD_IMM2_8";
1162         case ADD_IMM2: return "ADD_IMM2";
1163         case ADD_IMM2SX_8: return "ADD_IMM2SX_8";
1164         case ADD_2MEM_8: return "ADD_2MEM_8";
1165         case ADD_2MEM: return "ADD_2MEM";
1166         case ADD_MEM2_8: return "ADD_MEM2_8";
1167         case ADD_MEM2: return "ADD_MEM2";
1168         case AND_MEM2_8: return "AND_MEM2_8";
1169         case AND_MEM2: return "AND_MEM2";
1170         case AND_2MEM_8: return "AND_2MEM_8";
1171         case AND_2MEM: return "AND_2MEM";
1172         case AND_IMM2_8: return "AND_IMM2_8";
1173         case AND_IMM2: return "AND_IMM2";
1174         case AND_IMM2SX_8: return "AND_IMM2SX_8";
1175         case OR_2MEM_8: return "OR_2MEM_8";
1176         case OR_2MEM: return "OR_2MEM";
1177         case OR_MEM2_8: return "OR_MEM2_8";
1178         case OR_MEM2: return "OR_MEM2";
1179         case OR_IMM2_8: return "OR_IMM2_8";
1180         case OR_IMM2: return "OR_IMM2";
1181         case OR_IMM2SX_8: return "OR_IMM2SX_8";
1182         case SUB_2MEM_8: return "SUB_2MEM_8";
1183         case SUB_2MEM: return "SUB_2MEM";
1184         case SUB_MEM2_8: return "SUB_MEM2_8";
1185         case SUB_MEM2: return "SUB_MEM2";
1186         case SUB_IMM2_8: return "SUB_IMM2_8";
1187         case SUB_IMM2: return "SUB_IMM2";
1188         case SUB_IMM2SX_8: return "SUB_IMM2SX_8";
1189         case XOR_2MEM_8: return "XOR_2MEM_8";
1190         case XOR_2MEM: return "XOR_2MEM";
1191         case XOR_MEM2_8: return "XOR_MEM2_8";
1192         case XOR_MEM2: return "XOR_MEM2";
1193         case XOR_IMM2_8: return "XOR_IMM2_8";
1194         case XOR_IMM2: return "XOR_IMM2";
1195         case XOR_IMM2SX_8: return "XOR_IMM2SX_8";
1196         case INC_8: return "INC_8";
1197         case INC: return "INC";
1198         case DEC_8: return "DEC_8";
1199         case DEC: return "DEC";
1200         case NEG_8: return "NEG_8";
1201         case NEG: return "NEG"; 
1202         case NOT_8: return "NOT_8";
1203         case NOT: return "NOT";
1204         case XCHG_8: return "XCHG_8";
1205         case XCHG: return "XCHG";
1206         case SETB: return "SETB";
1207         case SETBE: return "SETBE";
1208         case SETL: return "SETL";
1209         case SETLE: return "SETLE";
1210         case SETNB: return "SETNB";
1211         case SETNBE: return "SETNBE";
1212         case SETNL: return "SETNL";
1213         case SETNLE: return "SETNLE";
1214         case SETNO: return "SETNO";
1215         case SETNP: return "SETNP";
1216         case SETNS: return "SETNS";
1217         case SETNZ: return "SETNZ";
1218         case SETP: return "SETP";
1219         case SETS: return "SETS";
1220         case SETZ: return "SETZ";
1221         case SETO: return "SETO";
1222         case STOS_8: return "STOS_8";
1223         case STOS: return "STOS";
1224
1225         case INVALID_INSTR:
1226         default:
1227             return "INVALID_INSTR";
1228     }
1229 }