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.


53831c45f0670e15289940bac85346c86936a4d9
[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     INT, 
32
33     MOV_CR2,
34     MOV_2CR,
35     MOV_DR2,
36     MOV_2DR,
37     MOV_SR2,
38     MOV_2SR,
39
40     MOV_MEM2_8,
41     MOV_MEM2,
42     MOV_2MEM_8,
43     MOV_2MEM,
44     MOV_MEM2AL_8,
45     MOV_MEM2AX,
46     MOV_AL2MEM_8,
47     MOV_AX2MEM,
48     MOV_IMM2_8,
49     MOV_IMM2,
50
51     MOVS_8,
52     MOVS,
53     MOVSX_8,
54     MOVSX,
55     MOVZX_8,
56     MOVZX,
57
58     HLT,
59     PUSHF,
60     POPF,
61
62     ADC_2MEM_8,
63     ADC_2MEM,
64     ADC_MEM2_8,
65     ADC_MEM2,
66     ADC_IMM2_8,
67     ADC_IMM2,
68     ADC_IMM2SX_8,
69     ADD_IMM2_8,
70     ADD_IMM2,
71     ADD_IMM2SX_8,
72     ADD_2MEM_8,
73     ADD_2MEM,
74     ADD_MEM2_8,
75     ADD_MEM2,
76     AND_MEM2_8,
77     AND_MEM2,
78     AND_2MEM_8,
79     AND_2MEM,
80     AND_IMM2_8,
81     AND_IMM2,
82     AND_IMM2SX_8,
83     OR_2MEM_8,
84     OR_2MEM,
85     OR_MEM2_8,
86     OR_MEM2,
87     OR_IMM2_8,
88     OR_IMM2,
89     OR_IMM2SX_8,
90     SUB_2MEM_8,
91     SUB_2MEM,
92     SUB_MEM2_8,
93     SUB_MEM2,
94     SUB_IMM2_8,
95     SUB_IMM2,
96     SUB_IMM2SX_8,
97     XOR_2MEM_8,
98     XOR_2MEM,
99     XOR_MEM2_8,
100     XOR_MEM2,
101     XOR_IMM2_8,
102     XOR_IMM2,
103     XOR_IMM2SX_8,
104
105     INC_8,
106     INC,
107     DEC_8,
108     DEC,
109     NEG_8,
110     NEG, 
111     NOT_8,
112     NOT,
113     XCHG_8,
114     XCHG,
115
116     SETB,
117     SETBE,
118     SETL,
119     SETLE,
120     SETNB,
121     SETNBE,
122     SETNL,
123     SETNLE,
124     SETNO,
125     SETNP,
126     SETNS,
127     SETNZ,
128     SETP,
129     SETS,
130     SETZ,
131     SETO,
132
133     STOS_8,
134     STOS
135 } op_form_t;
136
137
138 static int get_addr_width(struct guest_info * info, struct x86_instr * instr) {
139
140     switch (v3_get_vm_cpu_mode(info)) {
141         case REAL:
142             return (instr->prefixes.addr_size) ? 4 : 2;
143         case LONG:
144                 return 8;
145         case PROTECTED:
146         case PROTECTED_PAE:
147         case LONG_32_COMPAT:
148                 if (info->segments.cs.db) {
149                         return (instr->prefixes.addr_size) ? 2 : 4;
150                 } else {
151                         return (instr->prefixes.addr_size) ? 4 : 2;
152                 }                       
153         default:
154             PrintError("Unsupported CPU mode: %d\n", info->cpu_mode);
155             return -1;
156     }
157 }
158
159 static int get_operand_width(struct guest_info * info, struct x86_instr * instr, 
160                              op_form_t form) {
161     switch (form) {
162
163         case CLTS:
164         case HLT:
165             return 0;
166
167         case MOV_MEM2_8:
168         case MOV_2MEM_8:
169         case MOV_MEM2AL_8:
170         case MOV_AL2MEM_8:
171         case MOV_IMM2_8:
172         case MOVS_8:
173         case MOVSX_8:
174         case MOVZX_8:
175         case ADC_2MEM_8:
176         case ADC_MEM2_8:
177         case ADC_IMM2_8:
178         case ADD_IMM2_8:
179         case ADD_2MEM_8:
180         case ADD_MEM2_8:
181         case AND_MEM2_8:
182         case AND_2MEM_8:
183         case AND_IMM2_8:
184         case OR_2MEM_8:
185         case OR_MEM2_8:
186         case OR_IMM2_8:
187         case SUB_2MEM_8:
188         case XOR_2MEM_8:
189         case SUB_MEM2_8:
190         case SUB_IMM2_8:
191         case XOR_MEM2_8:
192         case XOR_IMM2_8:
193         case INC_8:
194         case INT:
195         case DEC_8:
196         case NEG_8:
197         case NOT_8:
198         case XCHG_8:
199         case STOS_8:
200         case SETB:
201         case SETBE:
202         case SETL:
203         case SETLE:
204         case SETNB:
205         case SETNBE:
206         case SETNL:
207         case SETNLE:
208         case SETNO:
209         case SETNP:
210         case SETNS:
211         case SETNZ:
212         case SETP:
213         case SETS:
214         case SETZ:
215         case SETO:
216             return 1;
217
218         case LMSW:
219         case SMSW:
220             return 2;
221
222         case MOV_MEM2:
223         case MOV_2MEM:
224         case MOV_MEM2AX:
225         case MOV_AX2MEM: 
226         case MOVS:
227         case MOVSX:
228         case MOVZX:
229         case ADC_2MEM:
230         case ADC_MEM2:
231         case ADC_IMM2:
232         case ADD_IMM2:
233         case ADD_2MEM:
234         case ADD_MEM2:
235         case AND_MEM2:
236         case AND_2MEM:
237         case AND_IMM2:
238         case OR_2MEM:
239         case OR_MEM2:
240         case OR_IMM2:
241         case SUB_2MEM:
242         case SUB_MEM2:
243         case SUB_IMM2:
244         case XOR_2MEM:
245         case XOR_MEM2:
246         case XOR_IMM2:
247         case INC:
248         case DEC:
249         case NEG: 
250         case NOT:
251         case STOS:
252         case XCHG:
253         case ADC_IMM2SX_8:
254         case AND_IMM2SX_8:
255         case ADD_IMM2SX_8:
256         case OR_IMM2SX_8:
257         case SUB_IMM2SX_8:
258         case XOR_IMM2SX_8:
259         case MOV_IMM2:
260             switch (v3_get_vm_cpu_mode(info)) {
261                 case REAL:
262                     return (instr->prefixes.op_size) ? 4 : 2;
263                 case LONG:
264                     if (instr->prefixes.rex_op_size) {
265                         return 8;
266                     } else {
267                         return (instr->prefixes.op_size) ? 2 : 4;
268                     }
269                 case PROTECTED:
270                 case PROTECTED_PAE:
271                 case LONG_32_COMPAT:
272                     if (info->segments.cs.db) {
273                         // default is 32
274                         return (instr->prefixes.op_size) ? 2 : 4;
275                     } else {
276                         return (instr->prefixes.op_size) ? 4 : 2;
277                     }
278                 default:
279                     PrintError("Unsupported CPU mode: %d\n", info->cpu_mode);
280                     return -1;
281             }
282         case INVLPG:
283             switch (v3_get_vm_cpu_mode(info)) {
284                 case REAL:
285                     PrintError("Invalid instruction given operating mode (%d)\n", form);
286                     return 0;
287                 case PROTECTED:
288                 case PROTECTED_PAE:
289                 case LONG_32_COMPAT:
290                         return 4;
291                 case LONG:
292                         return 8;
293                 default:
294                     PrintError("Unsupported CPU mode: %d\n", info->cpu_mode);
295                     return -1;
296             }
297
298         case PUSHF:
299         case POPF:
300             switch (v3_get_vm_cpu_mode(info)) {
301                 case REAL:
302                     return 2;
303                 case PROTECTED:
304                 case PROTECTED_PAE:
305                 case LONG_32_COMPAT:
306                         return 4;
307                 case LONG:
308                         return 8;
309                 default:
310                     PrintError("Unsupported CPU mode: %d\n", info->cpu_mode);
311                     return -1;
312             }
313
314         //case INT:
315         case MOV_DR2:
316         case MOV_2DR:
317         case MOV_CR2:
318         case MOV_2CR:
319             switch (v3_get_vm_cpu_mode(info)) {
320                 case REAL:
321                 case PROTECTED:
322                 case PROTECTED_PAE:
323                 case LONG_32_COMPAT:
324
325                         return 4;
326                 case LONG:
327                         return 8;
328                 default:
329                     PrintError("Unsupported CPU mode: %d\n", info->cpu_mode);
330                     return -1;
331             }
332
333         case MOV_SR2:
334         case MOV_2SR:
335         default:
336             PrintError("Unsupported instruction form %d\n", form);
337             return -1;
338         
339     }
340
341     return 0;
342 }
343
344
345
346 typedef enum {INVALID_ADDR_TYPE, REG, DISP0, DISP8, DISP16, DISP32} modrm_mode_t;
347 typedef enum {INVALID_REG_SIZE, REG64, REG32, REG16, REG8} reg_size_t;
348
349
350 struct modrm_byte {
351     uint_t rm   :   3;
352     uint_t reg  :   3;
353     uint_t mod  :   2;
354 } __attribute__((packed));
355
356
357 struct sib_byte {
358     uint_t base     :   3;
359     uint_t index    :   3;
360     uint_t scale    :   2;
361 } __attribute__((packed));
362
363
364
365
366 struct v3_gprs;
367
368 static inline int decode_gpr(struct guest_info * core,
369                              uint8_t reg_code,
370                              struct x86_operand * reg) {
371
372     struct v3_gprs * gprs = &(core->vm_regs);
373
374     switch (reg_code) {
375         case 0:
376             reg->operand = (addr_t)&(gprs->rax);
377             break;
378         case 1:
379             reg->operand = (addr_t)&(gprs->rcx);
380             break;
381         case 2:
382             reg->operand = (addr_t)&(gprs->rdx);
383             break;
384         case 3:
385             reg->operand = (addr_t)&(gprs->rbx);
386             break;
387         case 4:
388             if (reg->size == 1) {
389                 reg->operand = (addr_t)&(gprs->rax) + 1;
390             } else {
391                 reg->operand = (addr_t)&(gprs->rsp);
392             }
393             break;
394         case 5:
395             if (reg->size == 1) {
396                 reg->operand = (addr_t)&(gprs->rcx) + 1;
397             } else {
398                 reg->operand = (addr_t)&(gprs->rbp);
399             }
400             break;
401         case 6:
402             if (reg->size == 1) {
403                 reg->operand = (addr_t)&(gprs->rdx) + 1;
404             } else {
405                 reg->operand = (addr_t)&(gprs->rsi);
406             }
407             break;
408         case 7:
409             if (reg->size == 1) {
410                 reg->operand = (addr_t)&(gprs->rbx) + 1;
411             } else {
412                 reg->operand = (addr_t)&(gprs->rdi);
413             }
414             break;
415         case 8:
416             reg->operand = (addr_t)&(gprs->r8);
417             break;
418         case 9:
419             reg->operand = (addr_t)&(gprs->r9);
420             break;
421         case 10:
422             reg->operand = (addr_t)&(gprs->r10);
423             break;
424         case 11:
425             reg->operand = (addr_t)&(gprs->r11);
426             break;
427         case 12:
428             reg->operand = (addr_t)&(gprs->r12);
429             break;
430         case 13:
431             reg->operand = (addr_t)&(gprs->r13);
432             break;
433         case 14:
434             reg->operand = (addr_t)&(gprs->r14);
435             break;
436         case 15:
437             reg->operand = (addr_t)&(gprs->r15);
438             break;
439         default:
440             PrintError("Invalid Reg Code (%d)\n", reg_code);
441             reg->operand = 0;
442             return -1;
443     }
444
445     return 0;
446 }
447
448
449
450
451 static inline int decode_cr(struct guest_info * core,                   
452                              uint8_t reg_code,
453                              struct x86_operand * reg) {
454
455     struct v3_ctrl_regs * crs = &(core->ctrl_regs);
456
457 //    PrintDebug("\t Ctrl regs %d\n", reg_code);
458
459     switch (reg_code) {
460         case 0:
461             reg->operand = (addr_t)&(crs->cr0);
462             break;
463         case 2:
464             reg->operand = (addr_t)&(crs->cr2);
465             break;
466         case 3:
467             reg->operand = (addr_t)&(crs->cr3);
468             break;
469         case 4:
470             reg->operand = (addr_t)&(crs->cr4);
471             break;
472         default:
473             reg->operand = 0;
474             PrintError("Invalid Reg Code (%d)\n", reg_code);
475             return -1;
476     }
477
478     return 0;
479 }
480
481
482
483 #define ADDR_MASK(val, length) ({                             \
484             ullong_t mask = 0x0LL;                            \
485             switch (length) {                                 \
486                 case 2:                                       \
487                     mask = 0x00000000000fffffLL;              \
488                     break;                                    \
489                 case 4:                                       \
490                     mask = 0x00000000ffffffffLL;              \
491                     break;                                    \
492                 case 8:                                       \
493                     mask = 0xffffffffffffffffLL;              \
494                     break;                                    \
495             }                                                 \
496             val & mask;                                       \
497         })
498
499
500
501 static  int decode_rm_operand16(struct guest_info * core,
502                                 uint8_t * modrm_instr, 
503                                 struct x86_instr * instr,
504                                 struct x86_operand * operand, 
505                                 uint8_t * reg_code) { 
506
507     struct v3_gprs * gprs = &(core->vm_regs);
508     struct modrm_byte * modrm = (struct modrm_byte *)modrm_instr;
509     addr_t base_addr = 0;
510     modrm_mode_t mod_mode = 0;
511     uint8_t * instr_cursor = modrm_instr;
512
513     //  PrintDebug("ModRM mod=%d\n", modrm->mod);
514     
515     *reg_code = modrm->reg;
516
517     instr_cursor += 1;
518
519     if (modrm->mod == 3) {
520         //PrintDebug("first operand = Register (RM=%d)\n",modrm->rm);
521         operand->type = REG_OPERAND;
522
523         decode_gpr(core, modrm->rm, operand);
524
525     } else {
526         struct v3_segment * seg = NULL;
527
528         operand->type = MEM_OPERAND;
529
530         if (modrm->mod == 0) {
531             mod_mode = DISP0;
532         } else if (modrm->mod == 1) {
533             mod_mode = DISP8;
534         } else if (modrm->mod == 2) {
535             mod_mode = DISP16;
536         } else {
537             PrintError("Instruction format error: Invalid mod_rm mode (%d)\n", modrm->mod);
538             v3_print_instr(instr);
539             return -1;
540         }
541
542         switch (modrm->rm) {
543             case 0:
544                 base_addr = gprs->rbx + ADDR_MASK(gprs->rsi, 2);
545                 break;
546             case 1:
547                 base_addr = gprs->rbx + ADDR_MASK(gprs->rdi, 2);
548                 break;
549             case 2:
550                 base_addr = gprs->rbp + ADDR_MASK(gprs->rsi, 2);
551                 break;
552             case 3:
553                 base_addr = gprs->rbp + ADDR_MASK(gprs->rdi, 2);
554                 break;
555             case 4:
556                 base_addr = ADDR_MASK(gprs->rsi, 2);
557                 break;
558             case 5:
559                 base_addr = ADDR_MASK(gprs->rdi, 2);
560                 break;
561             case 6:
562                 if (modrm->mod == 0) {
563                     base_addr = 0;
564                     mod_mode = DISP16;
565                 } else {
566                     base_addr = ADDR_MASK(gprs->rbp, 2);
567                 }
568                 break;
569             case 7:
570                 base_addr = ADDR_MASK(gprs->rbx, 2);
571                 break;
572         }
573
574
575
576         if (mod_mode == DISP8) {
577             base_addr += *(sint8_t *)instr_cursor;
578             instr_cursor += 1;
579         } else if (mod_mode == DISP16) {
580             base_addr += *(sint16_t *)instr_cursor;
581             instr_cursor += 2;
582         }
583     
584         
585         // get appropriate segment
586         if (instr->prefixes.cs_override) {
587             seg = &(core->segments.cs);
588         } else if (instr->prefixes.es_override) {
589             seg = &(core->segments.es);
590         } else if (instr->prefixes.ss_override) {
591             seg = &(core->segments.ss);
592         } else if (instr->prefixes.fs_override) {
593             seg = &(core->segments.fs);
594         } else if (instr->prefixes.gs_override) {
595             seg = &(core->segments.gs);
596         } else {
597             seg = &(core->segments.ds);
598         }
599         
600         operand->operand = ADDR_MASK(get_addr_linear(core, base_addr, seg), 
601                                      get_addr_width(core, instr));
602     }
603
604
605     return (instr_cursor - modrm_instr);
606 }
607
608
609 // returns num_bytes parsed
610 static int decode_rm_operand32(struct guest_info * core, 
611                                uint8_t * modrm_instr,  
612                                struct x86_instr * instr,
613                                struct x86_operand * operand, 
614                                uint8_t * reg_code) {
615
616     struct v3_gprs * gprs = &(core->vm_regs);
617     uint8_t * instr_cursor = modrm_instr;
618     struct modrm_byte * modrm = (struct modrm_byte *)modrm_instr;
619     addr_t base_addr = 0;
620     modrm_mode_t mod_mode = 0;
621     uint_t has_sib_byte = 0;
622
623
624     *reg_code = modrm->reg;
625
626     instr_cursor += 1;
627
628     if (modrm->mod == 3) {
629         operand->type = REG_OPERAND;
630         //    PrintDebug("first operand = Register (RM=%d)\n",modrm->rm);
631
632         decode_gpr(core, modrm->rm, operand);
633
634     } else {
635         struct v3_segment * seg = NULL;
636
637         operand->type = MEM_OPERAND;
638
639         if (modrm->mod == 0) {
640             mod_mode = DISP0;
641         } else if (modrm->mod == 1) {
642             mod_mode = DISP8;
643         } else if (modrm->mod == 2) {
644             mod_mode = DISP32;
645         } else {
646             PrintError("Instruction format error: Invalid mod_rm mode (%d)\n", modrm->mod);
647             v3_print_instr(instr);
648             return -1;
649         }
650     
651         switch (modrm->rm) {
652             case 0:
653                 base_addr = gprs->rax;
654                 break;
655             case 1:
656                 base_addr = gprs->rcx;
657                 break;
658             case 2:
659                 base_addr = gprs->rdx;
660                 break;
661             case 3:
662                 base_addr = gprs->rbx;
663                 break;
664             case 4:
665                 has_sib_byte = 1;
666                 break;
667             case 5:
668                 if (modrm->mod == 0) {
669                     base_addr = 0;
670                     mod_mode = DISP32;
671                 } else {
672                     base_addr = gprs->rbp;
673                 }
674                 break;
675             case 6:
676                 base_addr = gprs->rsi;
677                 break;
678             case 7:
679                 base_addr = gprs->rdi;
680                 break;
681         }
682
683         if (has_sib_byte) {
684             instr_cursor += 1;
685             struct sib_byte * sib = (struct sib_byte *)(instr_cursor);
686             int scale = 0x1 << sib->scale;
687
688             instr_cursor += 1;
689
690             switch (sib->index) {
691                 case 0:
692                     base_addr = gprs->rax;
693                     break;
694                 case 1:
695                     base_addr = gprs->rcx;
696                     break;
697                 case 2:
698                     base_addr = gprs->rdx;
699                     break;
700                 case 3:
701                     base_addr = gprs->rbx;
702                     break;
703                 case 4:
704                     base_addr = 0;
705                     break;
706                 case 5:
707                     base_addr = gprs->rbp;
708                     break;
709                 case 6:
710                     base_addr = gprs->rsi;
711                     break;
712                 case 7:
713                     base_addr = gprs->rdi;
714                     break;
715             }
716
717             base_addr *= scale;
718
719
720             switch (sib->base) {
721                 case 0:
722                     base_addr += ADDR_MASK(gprs->rax, 4);
723                     break;
724                 case 1:
725                     base_addr += ADDR_MASK(gprs->rcx, 4);
726                     break;
727                 case 2:
728                     base_addr += ADDR_MASK(gprs->rdx, 4);
729                     break;
730                 case 3:
731                     base_addr += ADDR_MASK(gprs->rbx, 4);
732                     break;
733                 case 4:
734                     base_addr += ADDR_MASK(gprs->rsp, 4);
735                     break;
736                 case 5:
737                     if (modrm->mod != 0) {
738                         base_addr += ADDR_MASK(gprs->rbp, 4);
739                     }
740                     break;
741                 case 6:
742                     base_addr += ADDR_MASK(gprs->rsi, 4);
743                     break;
744                 case 7:
745                     base_addr += ADDR_MASK(gprs->rdi, 4);
746                     break;
747             }
748
749         } 
750
751
752         if (mod_mode == DISP8) {
753             base_addr += *(sint8_t *)instr_cursor;
754             instr_cursor += 1;
755         } else if (mod_mode == DISP32) {
756             base_addr += *(sint32_t *)instr_cursor;
757             instr_cursor += 4;
758         }
759     
760         // get appropriate segment
761         if (instr->prefixes.cs_override) {
762             seg = &(core->segments.cs);
763         } else if (instr->prefixes.es_override) {
764             seg = &(core->segments.es);
765         } else if (instr->prefixes.ss_override) {
766             seg = &(core->segments.ss);
767         } else if (instr->prefixes.fs_override) {
768             seg = &(core->segments.fs);
769         } else if (instr->prefixes.gs_override) {
770             seg = &(core->segments.gs);
771         } else {
772             seg = &(core->segments.ds);
773         }
774         
775         operand->operand = ADDR_MASK(get_addr_linear(core, base_addr, seg), 
776                                      get_addr_width(core, instr));
777     }
778
779
780     return (instr_cursor - modrm_instr);
781 }
782
783
784 int decode_rm_operand64(struct guest_info * core, uint8_t * modrm_instr, 
785                         struct x86_instr * instr, struct x86_operand * operand, 
786                         uint8_t * reg_code) {
787     
788     struct v3_gprs * gprs = &(core->vm_regs);
789     uint8_t * instr_cursor = modrm_instr;
790     struct modrm_byte * modrm = (struct modrm_byte *)modrm_instr;
791     addr_t base_addr = 0;
792     modrm_mode_t mod_mode = 0;
793     uint_t has_sib_byte = 0;
794
795
796     instr_cursor += 1;
797
798     *reg_code = modrm->reg;
799     *reg_code |= (instr->prefixes.rex_reg << 3);
800
801     if (modrm->mod == 3) {
802         uint8_t rm_val = modrm->rm;
803         
804         rm_val |= (instr->prefixes.rex_rm << 3);
805         
806         operand->type = REG_OPERAND;
807         //    PrintDebug("first operand = Register (RM=%d)\n",modrm->rm);
808         
809         decode_gpr(core, rm_val, operand);
810     } else {
811         struct v3_segment * seg = NULL;
812         uint8_t rm_val = modrm->rm;
813
814         operand->type = MEM_OPERAND;
815
816
817         if (modrm->mod == 0) {
818             mod_mode = DISP0;
819         } else if (modrm->mod == 1) {
820             mod_mode = DISP8;
821         } else if (modrm->mod == 2) {
822             mod_mode = DISP32;
823         } else {
824             PrintError("Instruction format error: Invalid mod_rm mode (%d)\n", modrm->mod);
825             v3_print_instr(instr);
826             return -1;
827         }
828     
829         if (rm_val == 4) {
830             has_sib_byte = 1;
831         } else {
832             rm_val |= (instr->prefixes.rex_rm << 3);
833             
834             switch (rm_val) {
835                 case 0:
836                     base_addr = gprs->rax;
837                     break;
838                 case 1:
839                     base_addr = gprs->rcx;
840                     break;
841                 case 2:
842                     base_addr = gprs->rdx;
843                     break;
844                 case 3:
845                     base_addr = gprs->rbx;
846                     break;
847                 case 5:
848                     if (modrm->mod == 0) {
849                         base_addr = 0;
850                         mod_mode = DISP32;
851                     } else {
852                         base_addr = gprs->rbp;
853                     }
854                     break;
855                 case 6:
856                     base_addr = gprs->rsi;
857                     break;
858                 case 7:
859                     base_addr = gprs->rdi;
860                     break;
861                 case 8:
862                     base_addr = gprs->r8;
863                     break;
864                 case 9:
865                     base_addr = gprs->r9;
866                     break;
867                 case 10:
868                     base_addr = gprs->r10;
869                     break;
870                 case 11:
871                     base_addr = gprs->r11;
872                     break;
873                 case 12:
874                     base_addr = gprs->r12;
875                     break;
876                 case 13:
877                     base_addr = gprs->r13;
878                     break;
879                 case 14:
880                     base_addr = gprs->r14;
881                     break;
882                 case 15:
883                     base_addr = gprs->r15;
884                     break;
885                 default:
886                     return -1;
887             }
888         }
889
890         if (has_sib_byte) {
891             instr_cursor += 1;
892             struct sib_byte * sib = (struct sib_byte *)(instr_cursor);
893             int scale = 0x1 << sib->scale;
894             uint8_t index_val = sib->index;
895             uint8_t base_val = sib->base;
896
897             index_val |= (instr->prefixes.rex_sib_idx << 3);
898             base_val |= (instr->prefixes.rex_rm << 3);
899
900             instr_cursor += 1;
901
902             switch (index_val) {
903                 case 0:
904                     base_addr = gprs->rax;
905                     break;
906                 case 1:
907                     base_addr = gprs->rcx;
908                     break;
909                 case 2:
910                     base_addr = gprs->rdx;
911                     break;
912                 case 3:
913                     base_addr = gprs->rbx;
914                     break;
915                 case 4:
916                     base_addr = 0;
917                     break;
918                 case 5:
919                     base_addr = gprs->rbp;
920                     break;
921                 case 6:
922                     base_addr = gprs->rsi;
923                     break;
924                 case 7:
925                     base_addr = gprs->rdi;
926                     break;
927                 case 8:
928                     base_addr = gprs->r8;
929                     break;
930                 case 9:
931                     base_addr = gprs->r9;
932                     break;
933                 case 10:
934                     base_addr = gprs->r10;
935                     break;
936                 case 11:
937                     base_addr = gprs->r11;
938                     break;
939                 case 12:
940                     base_addr = gprs->r12;
941                     break;
942                 case 13:
943                     base_addr = gprs->r13;
944                     break;
945                 case 14:
946                     base_addr = gprs->r14;
947                     break;
948                 case 15:
949                     base_addr = gprs->r15;
950                     break;
951             }
952
953             base_addr *= scale;
954
955
956             switch (base_val) {
957                 case 0:
958                     base_addr += gprs->rax;
959                     break;
960                 case 1:
961                     base_addr += gprs->rcx;
962                     break;
963                 case 2:
964                     base_addr += gprs->rdx;
965                     break;
966                 case 3:
967                     base_addr += gprs->rbx;
968                     break;
969                 case 4:
970                     base_addr += gprs->rsp;
971                     break;
972                 case 5:
973                     if (modrm->mod != 0) {
974                         base_addr += gprs->rbp;
975                     }
976                     break;
977                 case 6:
978                     base_addr += gprs->rsi;
979                     break;
980                 case 7:
981                     base_addr += gprs->rdi;
982                     break;
983                 case 8:
984                     base_addr += gprs->r8;
985                     break;
986                 case 9:
987                     base_addr += gprs->r9;
988                     break;
989                 case 10:
990                     base_addr += gprs->r10;
991                     break;
992                 case 11:
993                     base_addr += gprs->r11;
994                     break;
995                 case 12:
996                     base_addr += gprs->r12;
997                     break;
998                 case 13:
999                     base_addr += gprs->r13;
1000                     break;
1001                 case 14:
1002                     base_addr += gprs->r14;
1003                     break;
1004                 case 15:
1005                     base_addr += gprs->r15;
1006                     break;
1007             }
1008
1009         } 
1010
1011
1012         if (mod_mode == DISP8) {
1013             base_addr += *(sint8_t *)instr_cursor;
1014             instr_cursor += 1;
1015         } else if (mod_mode == DISP32) {
1016             base_addr += *(sint32_t *)instr_cursor;
1017             instr_cursor += 4;
1018         }
1019     
1020
1021         
1022         //Segments should be ignored 
1023         // get appropriate segment
1024
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) {
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         case 0xcd:
1338                 return INT;
1339
1340         case 0xf6: {
1341             struct modrm_byte * modrm = (struct modrm_byte *)&(instr[1]);
1342
1343             switch (modrm->reg) {
1344                 case 2:
1345                     return NOT_8;
1346                 case 3:
1347                     return NEG_8;
1348                 default:
1349                     return INVALID_INSTR;
1350             }
1351         }
1352         case 0xf7: {
1353             struct modrm_byte * modrm = (struct modrm_byte *)&(instr[1]);
1354
1355             switch (modrm->reg) {
1356                 case 2:
1357                     return NOT;
1358                 case 3:
1359                     return NEG;
1360                 default:
1361                     return INVALID_INSTR;
1362             }
1363         }
1364             
1365
1366         case 0xfe: {
1367             struct modrm_byte * modrm = (struct modrm_byte *)&(instr[1]);
1368
1369             switch (modrm->reg) {
1370                 case 0:
1371                     return INC_8;
1372                 case 1:
1373                     return DEC_8;
1374                 default:
1375                     return INVALID_INSTR;
1376             }
1377         }
1378
1379         case 0xff: {
1380             struct modrm_byte * modrm = (struct modrm_byte *)&(instr[1]);
1381
1382             switch (modrm->reg) {
1383                 case 0:
1384                     return INC;
1385                 case 1:
1386                     return DEC;
1387                 default:
1388                     return INVALID_INSTR;
1389             }
1390         }
1391
1392         default:
1393             return INVALID_INSTR;
1394     }
1395 }
1396
1397
1398
1399 static char * op_form_to_str(op_form_t form) {
1400
1401     switch (form) {
1402         case LMSW: return "LMSW";
1403         case SMSW: return "SMSW";
1404         case CLTS: return "CLTS";
1405         case INVLPG: return "INVLPG";
1406         case MOV_CR2: return "MOV_CR2";
1407         case MOV_2CR: return "MOV_2CR";
1408         case MOV_DR2: return "MOV_DR2";
1409         case MOV_2DR: return "MOV_2DR";
1410         case MOV_SR2: return "MOV_SR2";
1411         case MOV_2SR: return "MOV_2SR";
1412         case MOV_MEM2_8: return "MOV_MEM2_8";
1413         case MOV_MEM2: return "MOV_MEM2";
1414         case MOV_2MEM_8: return "MOV_2MEM_8";
1415         case MOV_2MEM: return "MOV_2MEM";
1416         case MOV_MEM2AL_8: return "MOV_MEM2AL_8";
1417         case MOV_MEM2AX: return "MOV_MEM2AX";
1418         case MOV_AL2MEM_8: return "MOV_AL2MEM_8";
1419         case MOV_AX2MEM: return "MOV_AX2MEM";
1420         case MOV_IMM2_8: return "MOV_IMM2_8";
1421         case MOV_IMM2: return "MOV_IMM2";
1422         case MOVS_8: return "MOVS_8";
1423         case MOVS: return "MOVS";
1424         case MOVSX_8: return "MOVSX_8";
1425         case MOVSX: return "MOVSX";
1426         case MOVZX_8: return "MOVZX_8";
1427         case MOVZX: return "MOVZX";
1428         case HLT: return "HLT";
1429         case PUSHF: return "PUSHF";
1430         case POPF: return "POPF";
1431         case ADC_2MEM_8: return "ADC_2MEM_8";
1432         case ADC_2MEM: return "ADC_2MEM";
1433         case ADC_MEM2_8: return "ADC_MEM2_8";
1434         case ADC_MEM2: return "ADC_MEM2";
1435         case ADC_IMM2_8: return "ADC_IMM2_8";
1436         case ADC_IMM2: return "ADC_IMM2";
1437         case ADC_IMM2SX_8: return "ADC_IMM2SX_8";
1438         case ADD_IMM2_8: return "ADD_IMM2_8";
1439         case ADD_IMM2: return "ADD_IMM2";
1440         case ADD_IMM2SX_8: return "ADD_IMM2SX_8";
1441         case ADD_2MEM_8: return "ADD_2MEM_8";
1442         case ADD_2MEM: return "ADD_2MEM";
1443         case ADD_MEM2_8: return "ADD_MEM2_8";
1444         case ADD_MEM2: return "ADD_MEM2";
1445         case AND_MEM2_8: return "AND_MEM2_8";
1446         case AND_MEM2: return "AND_MEM2";
1447         case AND_2MEM_8: return "AND_2MEM_8";
1448         case AND_2MEM: return "AND_2MEM";
1449         case AND_IMM2_8: return "AND_IMM2_8";
1450         case AND_IMM2: return "AND_IMM2";
1451         case AND_IMM2SX_8: return "AND_IMM2SX_8";
1452         case OR_2MEM_8: return "OR_2MEM_8";
1453         case OR_2MEM: return "OR_2MEM";
1454         case OR_MEM2_8: return "OR_MEM2_8";
1455         case OR_MEM2: return "OR_MEM2";
1456         case OR_IMM2_8: return "OR_IMM2_8";
1457         case OR_IMM2: return "OR_IMM2";
1458         case OR_IMM2SX_8: return "OR_IMM2SX_8";
1459         case SUB_2MEM_8: return "SUB_2MEM_8";
1460         case SUB_2MEM: return "SUB_2MEM";
1461         case SUB_MEM2_8: return "SUB_MEM2_8";
1462         case SUB_MEM2: return "SUB_MEM2";
1463         case SUB_IMM2_8: return "SUB_IMM2_8";
1464         case SUB_IMM2: return "SUB_IMM2";
1465         case SUB_IMM2SX_8: return "SUB_IMM2SX_8";
1466         case XOR_2MEM_8: return "XOR_2MEM_8";
1467         case XOR_2MEM: return "XOR_2MEM";
1468         case XOR_MEM2_8: return "XOR_MEM2_8";
1469         case XOR_MEM2: return "XOR_MEM2";
1470         case XOR_IMM2_8: return "XOR_IMM2_8";
1471         case XOR_IMM2: return "XOR_IMM2";
1472         case XOR_IMM2SX_8: return "XOR_IMM2SX_8";
1473         case INC_8: return "INC_8";
1474         case INC: return "INC";
1475         case DEC_8: return "DEC_8";
1476         case DEC: return "DEC";
1477         case NEG_8: return "NEG_8";
1478         case NEG: return "NEG"; 
1479         case NOT_8: return "NOT_8";
1480         case NOT: return "NOT";
1481         case XCHG_8: return "XCHG_8";
1482         case XCHG: return "XCHG";
1483         case SETB: return "SETB";
1484         case SETBE: return "SETBE";
1485         case SETL: return "SETL";
1486         case SETLE: return "SETLE";
1487         case SETNB: return "SETNB";
1488         case SETNBE: return "SETNBE";
1489         case SETNL: return "SETNL";
1490         case SETNLE: return "SETNLE";
1491         case SETNO: return "SETNO";
1492         case SETNP: return "SETNP";
1493         case SETNS: return "SETNS";
1494         case SETNZ: return "SETNZ";
1495         case SETP: return "SETP";
1496         case SETS: return "SETS";
1497         case SETZ: return "SETZ";
1498         case SETO: return "SETO";
1499         case STOS_8: return "STOS_8";
1500         case STOS: return "STOS";
1501         case INT: return "INT";
1502
1503         case INVALID_INSTR:
1504         default:
1505             return "INVALID_INSTR";
1506     }
1507 }