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.


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