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.


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