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.


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