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.


decoder fixes
[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 /* .... Giant fucking switch tables */
23
24
25 typedef enum {
26     INVALID_INSTR,
27     LMSW,
28     SMSW,
29     CLTS,
30     INVLPG,
31
32     MOV_CR2,
33     MOV_2CR,
34     MOV_DR2,
35     MOV_2DR,
36     MOV_SR2,
37     MOV_2SR,
38
39     MOV_MEM2_8,
40     MOV_MEM2,
41     MOV_2MEM_8,
42     MOV_2MEM,
43     MOV_MEM2AL_8,
44     MOV_MEM2AX,
45     MOV_AL2MEM_8,
46     MOV_AX2MEM,
47     MOV_IMM2_8,
48     MOV_IMM2,
49
50     MOVS_8,
51     MOVS,
52     MOVSX_8,
53     MOVSX,
54     MOVZX_8,
55     MOVZX,
56
57     HLT,
58     PUSHF,
59     POPF,
60
61     ADC_2MEM_8,
62     ADC_2MEM,
63     ADC_MEM2_8,
64     ADC_MEM2,
65     ADC_IMM2_8,
66     ADC_IMM2,
67     ADC_IMM2SX_8,
68     ADD_IMM2_8,
69     ADD_IMM2,
70     ADD_IMM2SX_8,
71     ADD_2MEM_8,
72     ADD_2MEM,
73     ADD_MEM2_8,
74     ADD_MEM2,
75     AND_MEM2_8,
76     AND_MEM2,
77     AND_2MEM_8,
78     AND_2MEM,
79     AND_IMM2_8,
80     AND_IMM2,
81     AND_IMM2SX_8,
82     OR_2MEM_8,
83     OR_2MEM,
84     OR_MEM2_8,
85     OR_MEM2,
86     OR_IMM2_8,
87     OR_IMM2,
88     OR_IMM2SX_8,
89     SUB_2MEM_8,
90     SUB_2MEM,
91     SUB_MEM2_8,
92     SUB_MEM2,
93     SUB_IMM2_8,
94     SUB_IMM2,
95     SUB_IMM2SX_8,
96     XOR_2MEM_8,
97     XOR_2MEM,
98     XOR_MEM2_8,
99     XOR_MEM2,
100     XOR_IMM2_8,
101     XOR_IMM2,
102     XOR_IMM2SX_8,
103
104     INC_8,
105     INC,
106     DEC_8,
107     DEC,
108     NEG_8,
109     NEG, 
110     NOT_8,
111     NOT,
112     XCHG_8,
113     XCHG,
114
115     SETB,
116     SETBE,
117     SETL,
118     SETLE,
119     SETNB,
120     SETNBE,
121     SETNL,
122     SETNLE,
123     SETNO,
124     SETNP,
125     SETNS,
126     SETNZ,
127     SETP,
128     SETS,
129     SETZ,
130     SETO,
131
132     STOS_8,
133     STOS
134 } op_form_t;
135
136
137 static int get_addr_width(struct guest_info * info, struct x86_instr * instr) {
138
139     switch (v3_get_vm_cpu_mode(info)) {
140         case REAL:
141             return (instr->prefixes.addr_size) ? 4 : 2;
142         case LONG:
143                 return 8;
144         case PROTECTED:
145         case PROTECTED_PAE:
146         case LONG_32_COMPAT:
147                 if (info->segments.cs.db) {
148                         return (instr->prefixes.addr_size) ? 2 : 4;
149                 } else {
150                         return (instr->prefixes.addr_size) ? 4 : 2;
151                 }                       
152         default:
153             PrintError("Unsupported CPU mode: %d\n", info->cpu_mode);
154             return -1;
155     }
156 }
157
158 static int get_operand_width(struct guest_info * info, struct x86_instr * instr, 
159                              op_form_t form) {
160     switch (form) {
161
162         case CLTS:
163         case HLT:
164             return 0;
165
166         case MOV_MEM2_8:
167         case MOV_2MEM_8:
168         case MOV_MEM2AL_8:
169         case MOV_AL2MEM_8:
170         case MOV_IMM2_8:
171         case MOVS_8:
172         case MOVSX_8:
173         case MOVZX_8:
174         case ADC_2MEM_8:
175         case ADC_MEM2_8:
176         case ADC_IMM2_8:
177         case ADD_IMM2_8:
178         case ADD_2MEM_8:
179         case ADD_MEM2_8:
180         case AND_MEM2_8:
181         case AND_2MEM_8:
182         case AND_IMM2_8:
183         case OR_2MEM_8:
184         case OR_MEM2_8:
185         case OR_IMM2_8:
186         case SUB_2MEM_8:
187         case XOR_2MEM_8:
188         case SUB_MEM2_8:
189         case SUB_IMM2_8:
190         case XOR_MEM2_8:
191         case XOR_IMM2_8:
192         case INC_8:
193         case DEC_8:
194         case NEG_8:
195         case NOT_8:
196         case XCHG_8:
197         case STOS_8:
198         case SETB:
199         case SETBE:
200         case SETL:
201         case SETLE:
202         case SETNB:
203         case SETNBE:
204         case SETNL:
205         case SETNLE:
206         case SETNO:
207         case SETNP:
208         case SETNS:
209         case SETNZ:
210         case SETP:
211         case SETS:
212         case SETZ:
213         case SETO:
214             return 1;
215
216         case LMSW:
217         case SMSW:
218             return 2;
219
220         case MOV_MEM2:
221         case MOV_2MEM:
222         case MOV_MEM2AX:
223         case MOV_AX2MEM:
224         case MOV_IMM2:      
225         case MOVS:
226         case MOVSX:
227         case MOVZX:
228         case ADC_2MEM:
229         case ADC_MEM2:
230         case ADC_IMM2:
231         case ADD_IMM2:
232         case ADD_2MEM:
233         case ADD_MEM2:
234         case AND_MEM2:
235         case AND_2MEM:
236         case AND_IMM2:
237         case OR_2MEM:
238         case OR_MEM2:
239         case OR_IMM2:
240         case SUB_2MEM:
241         case SUB_MEM2:
242         case SUB_IMM2:
243         case XOR_2MEM:
244         case XOR_MEM2:
245         case XOR_IMM2:
246         case INC:
247         case DEC:
248         case NEG: 
249         case NOT:
250         case STOS:
251         case XCHG:
252         case ADC_IMM2SX_8:
253         case AND_IMM2SX_8:
254         case ADD_IMM2SX_8:
255         case OR_IMM2SX_8:
256         case SUB_IMM2SX_8:
257         case XOR_IMM2SX_8:
258             switch (v3_get_vm_cpu_mode(info)) {
259                 case REAL:
260                     return (instr->prefixes.op_size) ? 4 : 2;
261                 case LONG:
262                     if (instr->prefixes.rex_op_size) {
263                         return 8;
264                     } else {
265                         return 4;
266                     }
267                 case PROTECTED:
268                 case PROTECTED_PAE:
269                 case LONG_32_COMPAT:
270                     if (info->segments.cs.db) {
271                         // default is 32
272                         return (instr->prefixes.op_size) ? 2 : 4;
273                     } else {
274                         return (instr->prefixes.op_size) ? 4 : 2;
275                     }
276                 default:
277                     PrintError("Unsupported CPU mode: %d\n", info->cpu_mode);
278                     return -1;
279             }
280             
281         case INVLPG:
282             switch (v3_get_vm_cpu_mode(info)) {
283                 case REAL:
284                     PrintError("Invalid instruction given operating mode (%d)\n", form);
285                     return 0;
286                 case PROTECTED:
287                 case PROTECTED_PAE:
288                 case LONG_32_COMPAT:
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
339     return 0;
340 }
341
342
343
344 typedef enum {INVALID_ADDR_TYPE, REG, DISP0, DISP8, DISP16, DISP32} modrm_mode_t;
345 typedef enum {INVALID_REG_SIZE, REG64, REG32, REG16, REG8} reg_size_t;
346
347
348 struct modrm_byte {
349     uint_t rm   :   3;
350     uint_t reg  :   3;
351     uint_t mod  :   2;
352 } __attribute__((packed));
353
354
355 struct sib_byte {
356     uint_t base     :   3;
357     uint_t index    :   3;
358     uint_t scale    :   2;
359 } __attribute__((packed));
360
361
362
363
364 struct v3_gprs;
365
366 static inline int decode_gpr(struct guest_info * core,
367                              uint8_t reg_code,
368                              struct x86_operand * reg) {
369
370     struct v3_gprs * gprs = &(core->vm_regs);
371
372     switch (reg_code) {
373         case 0:
374             reg->operand = (addr_t)&(gprs->rax);
375             break;
376         case 1:
377             reg->operand = (addr_t)&(gprs->rcx);
378             break;
379         case 2:
380             reg->operand = (addr_t)&(gprs->rdx);
381             break;
382         case 3:
383             reg->operand = (addr_t)&(gprs->rbx);
384             break;
385         case 4:
386             if (reg->size == 1) {
387                 reg->operand = (addr_t)&(gprs->rax) + 1;
388             } else {
389                 reg->operand = (addr_t)&(gprs->rsp);
390             }
391             break;
392         case 5:
393             if (reg->size == 1) {
394                 reg->operand = (addr_t)&(gprs->rcx) + 1;
395             } else {
396                 reg->operand = (addr_t)&(gprs->rbp);
397             }
398             break;
399         case 6:
400             if (reg->size == 1) {
401                 reg->operand = (addr_t)&(gprs->rdx) + 1;
402             } else {
403                 reg->operand = (addr_t)&(gprs->rsi);
404             }
405             break;
406         case 7:
407             if (reg->size == 1) {
408                 reg->operand = (addr_t)&(gprs->rbx) + 1;
409             } else {
410                 reg->operand = (addr_t)&(gprs->rdi);
411             }
412             break;
413         case 8:
414             reg->operand = (addr_t)&(gprs->r8);
415             break;
416         case 9:
417             reg->operand = (addr_t)&(gprs->r9);
418             break;
419         case 10:
420             reg->operand = (addr_t)&(gprs->r10);
421             break;
422         case 11:
423             reg->operand = (addr_t)&(gprs->r11);
424             break;
425         case 12:
426             reg->operand = (addr_t)&(gprs->r12);
427             break;
428         case 13:
429             reg->operand = (addr_t)&(gprs->r13);
430             break;
431         case 14:
432             reg->operand = (addr_t)&(gprs->r14);
433             break;
434         case 15:
435             reg->operand = (addr_t)&(gprs->r15);
436             break;
437         default:
438             PrintError("Invalid Reg Code (%d)\n", reg_code);
439             reg->operand = 0;
440             return -1;
441     }
442
443     return 0;
444 }
445
446
447
448
449 static inline int decode_cr(struct guest_info * core,                   
450                              uint8_t reg_code,
451                              struct x86_operand * reg) {
452
453     struct v3_ctrl_regs * crs = &(core->ctrl_regs);
454
455 //    PrintDebug("\t Ctrl regs %d\n", reg_code);
456
457     switch (reg_code) {
458         case 0:
459             reg->operand = (addr_t)&(crs->cr0);
460             break;
461         case 2:
462             reg->operand = (addr_t)&(crs->cr2);
463             break;
464         case 3:
465             reg->operand = (addr_t)&(crs->cr3);
466             break;
467         case 4:
468             reg->operand = (addr_t)&(crs->cr4);
469             break;
470         default:
471             reg->operand = 0;
472             PrintError("Invalid Reg Code (%d)\n", reg_code);
473             return -1;
474     }
475
476     return 0;
477 }
478
479 // This converts the displacement into the appropriate masked value
480 /* 
481    QUESTION: Are the register Values signed ?????
482  */
483 #define MASK_DISPLACEMENT(reg, mode) ({                                 \
484             sint64_t val = 0;                                           \
485             if (mode == DISP8) {                                        \
486                 val = (sint8_t)(reg & 0xff);                            \
487             } else if (mode == DISP16) {                                \
488                 val = (sint16_t)(reg & 0xffff);                         \
489             } else if (mode == DISP32) {                                \
490                 val = (sint32_t)(reg & 0xffffffff);                     \
491             } else {                                                    \
492                 PrintError("Error invalid displacement size (%d)\n", mode); \
493                 /*V3_ASSERT(0);*/                                       \
494             }                                                           \
495             val;                                                        \
496         })
497
498
499 #define ADDR_MASK(val, length) ({                             \
500             ullong_t mask = 0x0LL;                            \
501             switch (length) {                                 \
502                 case 2:                                       \
503                     mask = 0x00000000000fffffLL;              \
504                     break;                                    \
505                 case 4:                                       \
506                     mask = 0x00000000ffffffffLL;              \
507                     break;                                    \
508                 case 8:                                       \
509                     mask = 0xffffffffffffffffLL;              \
510                     break;                                    \
511             }                                                 \
512             val & mask;                                       \
513         })
514
515
516
517 static  int decode_rm_operand16(struct guest_info * core,
518                                 uint8_t * modrm_instr, 
519                                 struct x86_instr * instr,
520                                 struct x86_operand * operand, 
521                                 uint8_t * reg_code) { 
522
523     struct v3_gprs * gprs = &(core->vm_regs);
524     struct modrm_byte * modrm = (struct modrm_byte *)modrm_instr;
525     addr_t base_addr = 0;
526     modrm_mode_t mod_mode = 0;
527     uint8_t * instr_cursor = modrm_instr;
528
529     //  PrintDebug("ModRM mod=%d\n", modrm->mod);
530     
531     *reg_code = modrm->reg;
532
533     instr_cursor += 1;
534
535     if (modrm->mod == 3) {
536         //PrintDebug("first operand = Register (RM=%d)\n",modrm->rm);
537         operand->type = REG_OPERAND;
538
539         decode_gpr(core, modrm->rm, operand);
540
541     } else {
542         struct v3_segment * seg = NULL;
543
544         operand->type = MEM_OPERAND;
545
546         if (modrm->mod == 0) {
547             mod_mode = DISP0;
548         } else if (modrm->mod == 1) {
549             mod_mode = DISP8;
550         } else if (modrm->mod == 2) {
551             mod_mode = DISP16;
552         }
553
554         switch (modrm->rm) {
555             case 0:
556                 base_addr = gprs->rbx + MASK_DISPLACEMENT(gprs->rsi, mod_mode);
557                 break;
558             case 1:
559                 base_addr = gprs->rbx + MASK_DISPLACEMENT(gprs->rdi, mod_mode);
560                 break;
561             case 2:
562                 base_addr = gprs->rbp + MASK_DISPLACEMENT(gprs->rsi, mod_mode);
563                 break;
564             case 3:
565                 base_addr = gprs->rbp + MASK_DISPLACEMENT(gprs->rdi, mod_mode);
566                 break;
567             case 4:
568                 base_addr = gprs->rsi;
569                 break;
570             case 5:
571                 base_addr = gprs->rdi;
572                 break;
573             case 6:
574                 if (modrm->mod == 0) {
575                     base_addr = 0;
576                     mod_mode = DISP16;
577                 } else {
578                     base_addr = gprs->rbp;
579                 }
580                 break;
581             case 7:
582                 base_addr = gprs->rbx;
583                 break;
584         }
585
586
587
588         if (mod_mode == DISP8) {
589             base_addr += *(sint8_t *)instr_cursor;
590             instr_cursor += 1;
591         } else if (mod_mode == DISP16) {
592             base_addr += *(sint16_t *)instr_cursor;
593             instr_cursor += 2;
594         }
595     
596         
597         // get appropriate segment
598         if (instr->prefixes.cs_override) {
599             seg = &(core->segments.cs);
600         } else if (instr->prefixes.es_override) {
601             seg = &(core->segments.es);
602         } else if (instr->prefixes.ss_override) {
603             seg = &(core->segments.ss);
604         } else if (instr->prefixes.fs_override) {
605             seg = &(core->segments.fs);
606         } else if (instr->prefixes.gs_override) {
607             seg = &(core->segments.gs);
608         } else {
609             seg = &(core->segments.ds);
610         }
611         
612         operand->operand = ADDR_MASK(get_addr_linear(core, base_addr, seg), 
613                                      get_addr_width(core, instr));
614     }
615
616
617     return (instr_cursor - modrm_instr);
618 }
619
620
621 // returns num_bytes parsed
622 static int decode_rm_operand32(struct guest_info * core, 
623                                uint8_t * modrm_instr,  
624                                struct x86_instr * instr,
625                                struct x86_operand * operand, 
626                                uint8_t * reg_code) {
627
628     struct v3_gprs * gprs = &(core->vm_regs);
629     uint8_t * instr_cursor = modrm_instr;
630     struct modrm_byte * modrm = (struct modrm_byte *)modrm_instr;
631     addr_t base_addr = 0;
632     modrm_mode_t mod_mode = 0;
633     uint_t has_sib_byte = 0;
634
635
636     *reg_code = modrm->reg;
637
638     instr_cursor += 1;
639
640     if (modrm->mod == 3) {
641         operand->type = REG_OPERAND;
642         //    PrintDebug("first operand = Register (RM=%d)\n",modrm->rm);
643
644         decode_gpr(core, modrm->rm, operand);
645
646     } else {
647         struct v3_segment * seg = NULL;
648
649         operand->type = MEM_OPERAND;
650
651         if (modrm->mod == 0) {
652             mod_mode = DISP0;
653         } else if (modrm->mod == 1) {
654             mod_mode = DISP8;
655         } else if (modrm->mod == 2) {
656             mod_mode = DISP32;
657         }
658     
659         switch (modrm->rm) {
660             case 0:
661                 base_addr = gprs->rax;
662                 break;
663             case 1:
664                 base_addr = gprs->rcx;
665                 break;
666             case 2:
667                 base_addr = gprs->rdx;
668                 break;
669             case 3:
670                 base_addr = gprs->rbx;
671                 break;
672             case 4:
673                 has_sib_byte = 1;
674                 break;
675             case 5:
676                 if (modrm->mod == 0) {
677                     base_addr = 0;
678                     mod_mode = DISP32;
679                 } else {
680                     base_addr = gprs->rbp;
681                 }
682                 break;
683             case 6:
684                 base_addr = gprs->rsi;
685                 break;
686             case 7:
687                 base_addr = gprs->rdi;
688                 break;
689         }
690
691         if (has_sib_byte) {
692             instr_cursor += 1;
693             struct sib_byte * sib = (struct sib_byte *)(instr_cursor);
694             int scale = 0x1 << sib->scale;
695
696             instr_cursor += 1;
697
698             switch (sib->index) {
699                 case 0:
700                     base_addr = gprs->rax;
701                     break;
702                 case 1:
703                     base_addr = gprs->rcx;
704                     break;
705                 case 2:
706                     base_addr = gprs->rdx;
707                     break;
708                 case 3:
709                     base_addr = gprs->rbx;
710                     break;
711                 case 4:
712                     base_addr = 0;
713                     break;
714                 case 5:
715                     base_addr = gprs->rbp;
716                     break;
717                 case 6:
718                     base_addr = gprs->rsi;
719                     break;
720                 case 7:
721                     base_addr = gprs->rdi;
722                     break;
723             }
724
725             base_addr *= scale;
726
727
728             switch (sib->base) {
729                 case 0:
730                     base_addr += MASK_DISPLACEMENT(gprs->rax, mod_mode);
731                     break;
732                 case 1:
733                     base_addr += MASK_DISPLACEMENT(gprs->rcx, mod_mode);
734                     break;
735                 case 2:
736                     base_addr += MASK_DISPLACEMENT(gprs->rdx, mod_mode);
737                     break;
738                 case 3:
739                     base_addr += MASK_DISPLACEMENT(gprs->rbx, mod_mode);
740                     break;
741                 case 4:
742                     base_addr += MASK_DISPLACEMENT(gprs->rsp, mod_mode);
743                     break;
744                 case 5:
745                     if (modrm->mod != 0) {
746                         base_addr += MASK_DISPLACEMENT(gprs->rbp, mod_mode);
747                     }
748                     break;
749                 case 6:
750                     base_addr += MASK_DISPLACEMENT(gprs->rsi, mod_mode);
751                     break;
752                 case 7:
753                     base_addr += MASK_DISPLACEMENT(gprs->rdi, mod_mode);
754                     break;
755             }
756
757         } 
758
759
760         if (mod_mode == DISP8) {
761             base_addr += *(sint8_t *)instr_cursor;
762             instr_cursor += 1;
763         } else if (mod_mode == DISP32) {
764             base_addr += *(sint32_t *)instr_cursor;
765             instr_cursor += 4;
766         }
767     
768         // get appropriate segment
769         if (instr->prefixes.cs_override) {
770             seg = &(core->segments.cs);
771         } else if (instr->prefixes.es_override) {
772             seg = &(core->segments.es);
773         } else if (instr->prefixes.ss_override) {
774             seg = &(core->segments.ss);
775         } else if (instr->prefixes.fs_override) {
776             seg = &(core->segments.fs);
777         } else if (instr->prefixes.gs_override) {
778             seg = &(core->segments.gs);
779         } else {
780             seg = &(core->segments.ds);
781         }
782         
783         operand->operand = ADDR_MASK(get_addr_linear(core, base_addr, seg), 
784                                      get_addr_width(core, instr));
785     }
786
787
788     return (instr_cursor - modrm_instr);
789 }
790
791
792 int decode_rm_operand64(struct guest_info * core, uint8_t * modrm_instr, 
793                         struct x86_instr * instr, struct x86_operand * operand, 
794                         uint8_t * reg_code) {
795     
796     struct v3_gprs * gprs = &(core->vm_regs);
797     uint8_t * instr_cursor = modrm_instr;
798     struct modrm_byte * modrm = (struct modrm_byte *)modrm_instr;
799     addr_t base_addr = 0;
800     modrm_mode_t mod_mode = 0;
801     uint_t has_sib_byte = 0;
802
803
804     instr_cursor += 1;
805
806     *reg_code = modrm->reg;
807     *reg_code |= (instr->prefixes.rex_reg << 3);
808
809     if (modrm->mod == 3) {
810         uint8_t rm_val = modrm->rm;
811         
812         rm_val |= (instr->prefixes.rex_rm << 3);
813         
814         operand->type = REG_OPERAND;
815         //    PrintDebug("first operand = Register (RM=%d)\n",modrm->rm);
816         
817         decode_gpr(core, rm_val, operand);
818     } else {
819         struct v3_segment * seg = NULL;
820         uint8_t rm_val = modrm->rm;
821
822         operand->type = MEM_OPERAND;
823
824
825         if (modrm->mod == 0) {
826             mod_mode = DISP0;
827         } else if (modrm->mod == 1) {
828             mod_mode = DISP8;
829         } else if (modrm->mod == 2) {
830             mod_mode = DISP32;
831         }
832     
833         if (rm_val == 4) {
834             has_sib_byte = 1;
835         } else {
836             rm_val |= (instr->prefixes.rex_rm << 3);
837             
838             switch (rm_val) {
839                 case 0:
840                     base_addr = gprs->rax;
841                     break;
842                 case 1:
843                     base_addr = gprs->rcx;
844                     break;
845                 case 2:
846                     base_addr = gprs->rdx;
847                     break;
848                 case 3:
849                     base_addr = gprs->rbx;
850                     break;
851                 case 5:
852                     if (modrm->mod == 0) {
853                         base_addr = 0;
854                         mod_mode = DISP32;
855                     } else {
856                         base_addr = gprs->rbp;
857                     }
858                     break;
859                 case 6:
860                     base_addr = gprs->rsi;
861                     break;
862                 case 7:
863                     base_addr = gprs->rdi;
864                     break;
865                 case 8:
866                     base_addr = gprs->r8;
867                     break;
868                 case 9:
869                     base_addr = gprs->r9;
870                     break;
871                 case 10:
872                     base_addr = gprs->r10;
873                     break;
874                 case 11:
875                     base_addr = gprs->r11;
876                     break;
877                 case 12:
878                     base_addr = gprs->r12;
879                     break;
880                 case 13:
881                     base_addr = gprs->r13;
882                     break;
883                 case 14:
884                     base_addr = gprs->r14;
885                     break;
886                 case 15:
887                     base_addr = gprs->r15;
888                     break;
889                 default:
890                     return -1;
891             }
892         }
893
894         if (has_sib_byte) {
895             instr_cursor += 1;
896             struct sib_byte * sib = (struct sib_byte *)(instr_cursor);
897             int scale = 0x1 << sib->scale;
898             uint8_t index_val = sib->index;
899             uint8_t base_val = sib->base;
900
901             index_val |= (instr->prefixes.rex_sib_idx << 3);
902             base_val |= (instr->prefixes.rex_rm << 3);
903
904             instr_cursor += 1;
905
906             switch (index_val) {
907                 case 0:
908                     base_addr = gprs->rax;
909                     break;
910                 case 1:
911                     base_addr = gprs->rcx;
912                     break;
913                 case 2:
914                     base_addr = gprs->rdx;
915                     break;
916                 case 3:
917                     base_addr = gprs->rbx;
918                     break;
919                 case 4:
920                     base_addr = 0;
921                     break;
922                 case 5:
923                     base_addr = gprs->rbp;
924                     break;
925                 case 6:
926                     base_addr = gprs->rsi;
927                     break;
928                 case 7:
929                     base_addr = gprs->rdi;
930                     break;
931                 case 8:
932                     base_addr = gprs->r8;
933                     break;
934                 case 9:
935                     base_addr = gprs->r9;
936                     break;
937                 case 10:
938                     base_addr = gprs->r10;
939                     break;
940                 case 11:
941                     base_addr = gprs->r11;
942                     break;
943                 case 12:
944                     base_addr = gprs->r12;
945                     break;
946                 case 13:
947                     base_addr = gprs->r13;
948                     break;
949                 case 14:
950                     base_addr = gprs->r14;
951                     break;
952                 case 15:
953                     base_addr = gprs->r15;
954                     break;
955             }
956
957             base_addr *= scale;
958
959
960             switch (base_val) {
961                 case 0:
962                     base_addr += MASK_DISPLACEMENT(gprs->rax, mod_mode);
963                     break;
964                 case 1:
965                     base_addr += MASK_DISPLACEMENT(gprs->rcx, mod_mode);
966                     break;
967                 case 2:
968                     base_addr += MASK_DISPLACEMENT(gprs->rdx, mod_mode);
969                     break;
970                 case 3:
971                     base_addr += MASK_DISPLACEMENT(gprs->rbx, mod_mode);
972                     break;
973                 case 4:
974                     base_addr += MASK_DISPLACEMENT(gprs->rsp, mod_mode);
975                     break;
976                 case 5:
977                     if (modrm->mod != 0) {
978                         base_addr += MASK_DISPLACEMENT(gprs->rbp, mod_mode);
979                     }
980                     break;
981                 case 6:
982                     base_addr += MASK_DISPLACEMENT(gprs->rsi, mod_mode);
983                     break;
984                 case 7:
985                     base_addr += MASK_DISPLACEMENT(gprs->rdi, mod_mode);
986                     break;
987                 case 8:
988                     base_addr += MASK_DISPLACEMENT(gprs->r8, mod_mode);
989                     break;
990                 case 9:
991                     base_addr += MASK_DISPLACEMENT(gprs->r9, mod_mode);
992                     break;
993                 case 10:
994                     base_addr += MASK_DISPLACEMENT(gprs->r10, mod_mode);
995                     break;
996                 case 11:
997                     base_addr += MASK_DISPLACEMENT(gprs->r11, mod_mode);
998                     break;
999                 case 12:
1000                     base_addr += MASK_DISPLACEMENT(gprs->r12, mod_mode);
1001                     break;
1002                 case 13:
1003                     base_addr += MASK_DISPLACEMENT(gprs->r13, mod_mode);
1004                     break;
1005                 case 14:
1006                     base_addr += MASK_DISPLACEMENT(gprs->r14, mod_mode);
1007                     break;
1008                 case 15:
1009                     base_addr += MASK_DISPLACEMENT(gprs->r15, mod_mode);
1010                     break;
1011             }
1012
1013         } 
1014
1015
1016         if (mod_mode == DISP8) {
1017             base_addr += *(sint8_t *)instr_cursor;
1018             instr_cursor += 1;
1019         } else if (mod_mode == DISP32) {
1020             base_addr += *(sint32_t *)instr_cursor;
1021             instr_cursor += 4;
1022         }
1023     
1024
1025         /* 
1026            Segments should be ignored 
1027            // get appropriate segment
1028            if (instr->prefixes.cs_override) {
1029            seg = &(core->segments.cs);
1030            } else if (instr->prefixes.es_override) {
1031            seg = &(core->segments.es);
1032            } else if (instr->prefixes.ss_override) {
1033            seg = &(core->segments.ss);
1034            } else if (instr->prefixes.fs_override) {
1035            seg = &(core->segments.fs);
1036            } else if (instr->prefixes.gs_override) {
1037            seg = &(core->segments.gs);
1038            } else {
1039            seg = &(core->segments.ds);
1040            }
1041         */
1042
1043         operand->operand = ADDR_MASK(get_addr_linear(core, base_addr, seg), 
1044                                      get_addr_width(core, instr));
1045     }
1046
1047
1048     return (instr_cursor - modrm_instr);
1049
1050
1051 }
1052
1053
1054 static int decode_rm_operand(struct guest_info * core, 
1055                              uint8_t * instr_ptr,        // input
1056                              op_form_t form, 
1057                              struct x86_instr * instr,
1058                              struct x86_operand * operand, 
1059                              uint8_t * reg_code) {
1060     
1061     v3_cpu_mode_t mode = v3_get_vm_cpu_mode(core);
1062
1063     operand->size = get_operand_width(core, instr, form);
1064
1065     switch (mode) {
1066         case REAL:
1067             return decode_rm_operand16(core, instr_ptr, instr, operand, reg_code);
1068         case LONG:
1069             if (instr->prefixes.rex_op_size) {
1070                 return decode_rm_operand64(core, instr_ptr, instr, operand, reg_code);
1071             }
1072         case PROTECTED:
1073         case PROTECTED_PAE:
1074         case LONG_32_COMPAT:
1075             return decode_rm_operand32(core, instr_ptr, instr, operand, reg_code);
1076         default:
1077             PrintError("Invalid CPU_MODE (%d)\n", mode);
1078             return -1;
1079     }
1080 }
1081                              
1082
1083
1084 static inline op_form_t op_code_to_form_0f(uint8_t * instr, int * length) {
1085     *length += 1;
1086
1087     switch (instr[1]) {
1088         case 0x01: {
1089             struct modrm_byte * modrm = (struct modrm_byte *)&(instr[2]);
1090
1091             switch (modrm->reg) {
1092                 case 4:
1093                     return SMSW;
1094                 case 6:
1095                     return LMSW;
1096                 case 7:
1097                     return INVLPG;
1098                 default:
1099                     return INVALID_INSTR;
1100             }
1101         }
1102
1103         case 0x06:
1104             return CLTS;
1105         case 0x20:
1106             return MOV_CR2;
1107         case 0x21:
1108             return MOV_DR2;
1109
1110         case 0x22:
1111             return MOV_2CR;
1112         case 0x23:
1113             return MOV_2DR;
1114
1115         case 0x90:
1116             return SETO;
1117         case 0x91:
1118             return SETNO;
1119         case 0x92:
1120             return SETB;
1121         case 0x93:
1122             return SETNB;
1123         case 0x94:
1124             return SETZ;
1125         case 0x95:
1126             return SETNZ;
1127         case 0x96:
1128             return SETBE;
1129         case 0x97:
1130             return SETNBE;
1131         case 0x98:
1132             return SETS;
1133         case 0x99:
1134             return SETNS;
1135         case 0x9a:
1136             return SETP;
1137         case 0x9b:
1138             return SETNP;
1139         case 0x9c:
1140             return SETL;
1141         case 0x9d:
1142             return SETNL;
1143         case 0x9e:
1144             return SETLE;
1145         case 0x9f:
1146             return SETNLE;
1147
1148         case 0xb6:
1149             return MOVZX_8;
1150         case 0xb7:
1151             return MOVZX;
1152
1153         case 0xbe:
1154             return MOVSX_8;
1155         case 0xbf:
1156             return MOVSX;
1157             
1158
1159         default:
1160             return INVALID_INSTR;
1161     }
1162 }
1163
1164
1165 static op_form_t op_code_to_form(uint8_t * instr, int * length) {
1166     *length += 1;
1167
1168     switch (instr[0]) {
1169         case 0x00:
1170             return ADD_2MEM_8;
1171         case 0x01:
1172             return ADD_2MEM;
1173         case 0x02:
1174             return ADD_MEM2_8;
1175         case 0x03:
1176             return ADD_MEM2;
1177
1178         case 0x08:
1179             return OR_2MEM_8;
1180         case 0x09:
1181             return OR_2MEM;
1182         case 0x0a:
1183             return OR_MEM2_8;
1184         case 0x0b:
1185             return OR_MEM2;
1186
1187
1188         case 0x0f:
1189             return op_code_to_form_0f(instr, length);
1190
1191         case 0x10:
1192             return ADC_2MEM_8;
1193         case 0x11:
1194             return ADC_2MEM;
1195         case 0x12:
1196             return ADC_MEM2_8;
1197         case 0x13:
1198             return ADC_MEM2;
1199
1200         case 0x20:
1201             return AND_2MEM_8; 
1202         case 0x21:
1203             return AND_2MEM;
1204         case 0x22:
1205             return AND_MEM2_8;
1206         case 0x23:
1207             return AND_MEM2;
1208
1209         case 0x28:
1210             return SUB_2MEM_8;
1211         case 0x29:
1212             return SUB_2MEM;
1213         case 0x2a:
1214             return SUB_MEM2_8;
1215         case 0x2b:
1216             return SUB_MEM2;
1217
1218
1219         case 0x30:
1220             return XOR_2MEM_8;
1221         case 0x31:
1222             return XOR_2MEM;
1223         case 0x32:
1224             return XOR_MEM2_8;
1225         case 0x33:
1226             return XOR_MEM2;
1227
1228         case 0x80:{
1229             struct modrm_byte * modrm = (struct modrm_byte *)&(instr[1]);
1230
1231             switch (modrm->reg) {
1232                 case 0:
1233                     return ADD_IMM2_8;
1234                 case 1:
1235                     return OR_IMM2_8;
1236                 case 2:
1237                     return ADC_IMM2_8;
1238                 case 4:
1239                     return AND_IMM2_8;
1240                 case 5:
1241                     return SUB_IMM2_8;
1242                 case 6:
1243                     return XOR_IMM2_8;
1244                 default:
1245                     return INVALID_INSTR;
1246             }
1247         }
1248         case 0x81: {
1249             struct modrm_byte * modrm = (struct modrm_byte *)&(instr[1]);
1250             
1251             switch (modrm->reg) {
1252                 case 0:
1253                     return ADD_IMM2;
1254                 case 1:
1255                     return OR_IMM2;
1256                 case 2:
1257                     return ADC_IMM2;
1258                 case 4:
1259                     return AND_IMM2;
1260                 case 5:
1261                     return SUB_IMM2;
1262                 case 6:
1263                     return XOR_IMM2;
1264                 default:
1265                     return INVALID_INSTR;
1266             }
1267         }
1268         case 0x83: {
1269             struct modrm_byte * modrm = (struct modrm_byte *)&(instr[1]);
1270
1271             switch (modrm->reg) {
1272                 case 0:
1273                     return ADD_IMM2SX_8;
1274                 case 1:
1275                     return OR_IMM2SX_8;
1276                 case 2:
1277                     return ADC_IMM2SX_8;
1278                 case 4:
1279                     return AND_IMM2SX_8;
1280                 case 5:
1281                     return SUB_IMM2SX_8;
1282                 case 6:
1283                     return XOR_IMM2SX_8;
1284                 default:
1285                     return INVALID_INSTR;
1286             }
1287         }
1288
1289         case 0x86:
1290             return XCHG_8;
1291         case 0x87:
1292             return XCHG;
1293         case 0x88:
1294             return MOV_2MEM_8;
1295         case 0x89:
1296             return MOV_2MEM;
1297         case 0x8a:
1298             return MOV_MEM2_8;
1299         case 0x8b:
1300             return MOV_MEM2;
1301             
1302         case 0x8c:
1303             return MOV_SR2;
1304         case 0x8e:
1305             return MOV_2SR;
1306
1307
1308         case 0x9c:
1309             return PUSHF;
1310         case 0x9d:
1311             return POPF;
1312
1313         case 0xa0:
1314             return MOV_MEM2AL_8;
1315         case 0xa1:
1316             return MOV_MEM2AX;
1317         case 0xa2:
1318             return MOV_AL2MEM_8;
1319         case 0xa3:
1320             return MOV_AX2MEM;
1321
1322         case 0xa4:
1323             return MOVS_8;
1324         case 0xa5:
1325             return MOVS;
1326
1327         case 0xaa:
1328             return STOS_8;
1329         case 0xab:
1330             return STOS;
1331
1332         case 0xc6:
1333             return MOV_IMM2_8;
1334         case 0xc7:
1335             return MOV_IMM2;
1336
1337         case 0xf4:
1338             return HLT;
1339
1340
1341         case 0xf6: {
1342             struct modrm_byte * modrm = (struct modrm_byte *)&(instr[1]);
1343
1344             switch (modrm->reg) {
1345                 case 2:
1346                     return NOT_8;
1347                 case 3:
1348                     return NEG_8;
1349                 default:
1350                     return INVALID_INSTR;
1351             }
1352         }
1353         case 0xf7: {
1354             struct modrm_byte * modrm = (struct modrm_byte *)&(instr[1]);
1355
1356             switch (modrm->reg) {
1357                 case 2:
1358                     return NOT;
1359                 case 3:
1360                     return NEG;
1361                 default:
1362                     return INVALID_INSTR;
1363             }
1364         }
1365             
1366
1367         case 0xfe: {
1368             struct modrm_byte * modrm = (struct modrm_byte *)&(instr[1]);
1369
1370             switch (modrm->reg) {
1371                 case 0:
1372                     return INC_8;
1373                 case 1:
1374                     return DEC_8;
1375                 default:
1376                     return INVALID_INSTR;
1377             }
1378         }
1379
1380         case 0xff: {
1381             struct modrm_byte * modrm = (struct modrm_byte *)&(instr[1]);
1382
1383             switch (modrm->reg) {
1384                 case 0:
1385                     return INC;
1386                 case 1:
1387                     return DEC;
1388                 default:
1389                     return INVALID_INSTR;
1390             }
1391         }
1392
1393         default:
1394             return INVALID_INSTR;
1395     }
1396 }
1397
1398
1399
1400 static char * op_form_to_str(op_form_t form) {
1401
1402     switch (form) {
1403         case LMSW: return "LMSW";
1404         case SMSW: return "SMSW";
1405         case CLTS: return "CLTS";
1406         case INVLPG: return "INVLPG";
1407         case MOV_CR2: return "MOV_CR2";
1408         case MOV_2CR: return "MOV_2CR";
1409         case MOV_DR2: return "MOV_DR2";
1410         case MOV_2DR: return "MOV_2DR";
1411         case MOV_SR2: return "MOV_SR2";
1412         case MOV_2SR: return "MOV_2SR";
1413         case MOV_MEM2_8: return "MOV_MEM2_8";
1414         case MOV_MEM2: return "MOV_MEM2";
1415         case MOV_2MEM_8: return "MOV_2MEM_8";
1416         case MOV_2MEM: return "MOV_2MEM";
1417         case MOV_MEM2AL_8: return "MOV_MEM2AL_8";
1418         case MOV_MEM2AX: return "MOV_MEM2AX";
1419         case MOV_AL2MEM_8: return "MOV_AL2MEM_8";
1420         case MOV_AX2MEM: return "MOV_AX2MEM";
1421         case MOV_IMM2_8: return "MOV_IMM2_8";
1422         case MOV_IMM2: return "MOV_IMM2";
1423         case MOVS_8: return "MOVS_8";
1424         case MOVS: return "MOVS";
1425         case MOVSX_8: return "MOVSX_8";
1426         case MOVSX: return "MOVSX";
1427         case MOVZX_8: return "MOVZX_8";
1428         case MOVZX: return "MOVZX";
1429         case HLT: return "HLT";
1430         case PUSHF: return "PUSHF";
1431         case POPF: return "POPF";
1432         case ADC_2MEM_8: return "ADC_2MEM_8";
1433         case ADC_2MEM: return "ADC_2MEM";
1434         case ADC_MEM2_8: return "ADC_MEM2_8";
1435         case ADC_MEM2: return "ADC_MEM2";
1436         case ADC_IMM2_8: return "ADC_IMM2_8";
1437         case ADC_IMM2: return "ADC_IMM2";
1438         case ADC_IMM2SX_8: return "ADC_IMM2SX_8";
1439         case ADD_IMM2_8: return "ADD_IMM2_8";
1440         case ADD_IMM2: return "ADD_IMM2";
1441         case ADD_IMM2SX_8: return "ADD_IMM2SX_8";
1442         case ADD_2MEM_8: return "ADD_2MEM_8";
1443         case ADD_2MEM: return "ADD_2MEM";
1444         case ADD_MEM2_8: return "ADD_MEM2_8";
1445         case ADD_MEM2: return "ADD_MEM2";
1446         case AND_MEM2_8: return "AND_MEM2_8";
1447         case AND_MEM2: return "AND_MEM2";
1448         case AND_2MEM_8: return "AND_2MEM_8";
1449         case AND_2MEM: return "AND_2MEM";
1450         case AND_IMM2_8: return "AND_IMM2_8";
1451         case AND_IMM2: return "AND_IMM2";
1452         case AND_IMM2SX_8: return "AND_IMM2SX_8";
1453         case OR_2MEM_8: return "OR_2MEM_8";
1454         case OR_2MEM: return "OR_2MEM";
1455         case OR_MEM2_8: return "OR_MEM2_8";
1456         case OR_MEM2: return "OR_MEM2";
1457         case OR_IMM2_8: return "OR_IMM2_8";
1458         case OR_IMM2: return "OR_IMM2";
1459         case OR_IMM2SX_8: return "OR_IMM2SX_8";
1460         case SUB_2MEM_8: return "SUB_2MEM_8";
1461         case SUB_2MEM: return "SUB_2MEM";
1462         case SUB_MEM2_8: return "SUB_MEM2_8";
1463         case SUB_MEM2: return "SUB_MEM2";
1464         case SUB_IMM2_8: return "SUB_IMM2_8";
1465         case SUB_IMM2: return "SUB_IMM2";
1466         case SUB_IMM2SX_8: return "SUB_IMM2SX_8";
1467         case XOR_2MEM_8: return "XOR_2MEM_8";
1468         case XOR_2MEM: return "XOR_2MEM";
1469         case XOR_MEM2_8: return "XOR_MEM2_8";
1470         case XOR_MEM2: return "XOR_MEM2";
1471         case XOR_IMM2_8: return "XOR_IMM2_8";
1472         case XOR_IMM2: return "XOR_IMM2";
1473         case XOR_IMM2SX_8: return "XOR_IMM2SX_8";
1474         case INC_8: return "INC_8";
1475         case INC: return "INC";
1476         case DEC_8: return "DEC_8";
1477         case DEC: return "DEC";
1478         case NEG_8: return "NEG_8";
1479         case NEG: return "NEG"; 
1480         case NOT_8: return "NOT_8";
1481         case NOT: return "NOT";
1482         case XCHG_8: return "XCHG_8";
1483         case XCHG: return "XCHG";
1484         case SETB: return "SETB";
1485         case SETBE: return "SETBE";
1486         case SETL: return "SETL";
1487         case SETLE: return "SETLE";
1488         case SETNB: return "SETNB";
1489         case SETNBE: return "SETNBE";
1490         case SETNL: return "SETNL";
1491         case SETNLE: return "SETNLE";
1492         case SETNO: return "SETNO";
1493         case SETNP: return "SETNP";
1494         case SETNS: return "SETNS";
1495         case SETNZ: return "SETNZ";
1496         case SETP: return "SETP";
1497         case SETS: return "SETS";
1498         case SETZ: return "SETZ";
1499         case SETO: return "SETO";
1500         case STOS_8: return "STOS_8";
1501         case STOS: return "STOS";
1502
1503         case INVALID_INSTR:
1504         default:
1505             return "INVALID_INSTR";
1506     }
1507 }