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