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.


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