Palacios Public Git Repository

To checkout Palacios execute

  git clone http://v3vee.org/palacios/palacios.web/palacios.git
This will give you the master branch. You probably want the devel branch or one of the release branches. To switch to the devel branch, simply execute
  cd palacios
  git checkout --track -b devel origin/devel
The other branches are similar.


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