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.


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