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