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.


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