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.


6e33c462081d733ad2e327e299335d814124865a
[palacios.git] / palacios / include / palacios / vmm_instr_decoder.h
1 /*
2  * This file is part of the Palacios Virtual Machine Monitor developed
3  * by the V3VEE Project with funding from the United States National 
4  * Science Foundation and the Department of Energy.  
5  *
6  * The V3VEE Project is a joint project between Northwestern University
7  * and the University of New Mexico.  You can find out more at 
8  * http://www.v3vee.org
9  *
10  * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu> 
11  * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org> 
12  * All rights reserved.
13  *
14  * Author: Jack Lange <jarusl@cs.northwestern.edu>
15  *
16  * This is free software.  You are permitted to use,
17  * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
18  */
19
20 #include <palacios/vmm_types.h>
21
22 /* .... Giant fucking switch tables */
23
24
25 typedef enum {
26     INVALID_INSTR,
27     LMSW,
28     SMSW,
29     CLTS,
30     INVLPG,
31     INT, 
32
33     MOV_CR2,
34     MOV_2CR,
35     MOV_DR2,
36     MOV_2DR,
37     MOV_SR2,
38     MOV_2SR,
39
40     MOV_MEM2_8,
41     MOV_MEM2,
42     MOV_2MEM_8,
43     MOV_2MEM,
44     MOV_MEM2AL_8,
45     MOV_MEM2AX,
46     MOV_AL2MEM_8,
47     MOV_AX2MEM,
48     MOV_IMM2_8,
49     MOV_IMM2,
50
51     MOVS_8,
52     MOVS,
53     MOVSX_8,
54     MOVSX,
55     MOVZX_8,
56     MOVZX,
57
58     HLT,
59     PUSHF,
60     POPF,
61
62     ADC_2MEM_8,
63     ADC_2MEM,
64     ADC_MEM2_8,
65     ADC_MEM2,
66     ADC_IMM2_8,
67     ADC_IMM2,
68     ADC_IMM2SX_8,
69     ADD_IMM2_8,
70     ADD_IMM2,
71     ADD_IMM2SX_8,
72     ADD_2MEM_8,
73     ADD_2MEM,
74     ADD_MEM2_8,
75     ADD_MEM2,
76     AND_MEM2_8,
77     AND_MEM2,
78     AND_2MEM_8,
79     AND_2MEM,
80     AND_IMM2_8,
81     AND_IMM2,
82     AND_IMM2SX_8,
83     OR_2MEM_8,
84     OR_2MEM,
85     OR_MEM2_8,
86     OR_MEM2,
87     OR_IMM2_8,
88     OR_IMM2,
89     OR_IMM2SX_8,
90     SUB_2MEM_8,
91     SUB_2MEM,
92     SUB_MEM2_8,
93     SUB_MEM2,
94     SUB_IMM2_8,
95     SUB_IMM2,
96     SUB_IMM2SX_8,
97     XOR_2MEM_8,
98     XOR_2MEM,
99     XOR_MEM2_8,
100     XOR_MEM2,
101     XOR_IMM2_8,
102     XOR_IMM2,
103     XOR_IMM2SX_8,
104
105     INC_8,
106     INC,
107     DEC_8,
108     DEC,
109     NEG_8,
110     NEG, 
111     NOT_8,
112     NOT,
113     XCHG_8,
114     XCHG,
115
116     SETB,
117     SETBE,
118     SETL,
119     SETLE,
120     SETNB,
121     SETNBE,
122     SETNL,
123     SETNLE,
124     SETNO,
125     SETNP,
126     SETNS,
127     SETNZ,
128     SETP,
129     SETS,
130     SETZ,
131     SETO,
132
133     STOS_8,
134     STOS
135 } op_form_t;
136
137
138 static int get_addr_width(struct guest_info * info, struct x86_instr * instr) {
139
140     switch (v3_get_vm_cpu_mode(info)) {
141         case REAL:
142             return (instr->prefixes.addr_size) ? 4 : 2;
143         case LONG:
144                 return 8;
145         case PROTECTED:
146         case PROTECTED_PAE:
147         case LONG_32_COMPAT:
148                 if (info->segments.cs.db) {
149                         return (instr->prefixes.addr_size) ? 2 : 4;
150                 } else {
151                         return (instr->prefixes.addr_size) ? 4 : 2;
152                 }                       
153         default:
154             PrintError("Unsupported CPU mode: %d\n", info->cpu_mode);
155             return -1;
156     }
157 }
158
159 static int get_operand_width(struct guest_info * info, struct x86_instr * instr, 
160                              op_form_t form) {
161     switch (form) {
162
163         case CLTS:
164         case HLT:
165             return 0;
166
167         case MOV_MEM2_8:
168         case MOV_2MEM_8:
169         case MOV_MEM2AL_8:
170         case MOV_AL2MEM_8:
171         case MOV_IMM2_8:
172         case MOVS_8:
173         case MOVSX_8:
174         case MOVZX_8:
175         case ADC_2MEM_8:
176         case ADC_MEM2_8:
177         case ADC_IMM2_8:
178         case ADD_IMM2_8:
179         case ADD_2MEM_8:
180         case ADD_MEM2_8:
181         case AND_MEM2_8:
182         case AND_2MEM_8:
183         case AND_IMM2_8:
184         case OR_2MEM_8:
185         case OR_MEM2_8:
186         case OR_IMM2_8:
187         case SUB_2MEM_8:
188         case XOR_2MEM_8:
189         case SUB_MEM2_8:
190         case SUB_IMM2_8:
191         case XOR_MEM2_8:
192         case XOR_IMM2_8:
193         case INC_8:
194         case 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 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         case MOV_IMM2:
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 (instr->prefixes.op_size) ? 2 : 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         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 INT:
314         case MOV_DR2:
315         case MOV_2DR:
316         case MOV_CR2:
317         case MOV_2CR:
318             switch (v3_get_vm_cpu_mode(info)) {
319                 case REAL:
320                 case PROTECTED:
321                 case PROTECTED_PAE:
322                 case LONG_32_COMPAT:
323
324                         return 4;
325                 case LONG:
326                         return 8;
327                 default:
328                     PrintError("Unsupported CPU mode: %d\n", info->cpu_mode);
329                     return -1;
330             }
331
332         case MOV_SR2:
333         case MOV_2SR:
334         default:
335             PrintError("Unsupported instruction form %d\n", form);
336             return -1;
337         
338     }
339
340     return 0;
341 }
342
343
344
345 typedef enum {INVALID_ADDR_TYPE, REG, DISP0, DISP8, DISP16, DISP32} modrm_mode_t;
346 typedef enum {INVALID_REG_SIZE, REG64, REG32, REG16, REG8} reg_size_t;
347
348
349 struct modrm_byte {
350     uint_t rm   :   3;
351     uint_t reg  :   3;
352     uint_t mod  :   2;
353 } __attribute__((packed));
354
355
356 struct sib_byte {
357     uint_t base     :   3;
358     uint_t index    :   3;
359     uint_t scale    :   2;
360 } __attribute__((packed));
361
362
363
364
365 struct v3_gprs;
366
367 static inline int decode_gpr(struct guest_info * core,
368                              uint8_t reg_code,
369                              struct x86_operand * reg) {
370
371     struct v3_gprs * gprs = &(core->vm_regs);
372
373     switch (reg_code) {
374         case 0:
375             reg->operand = (addr_t)&(gprs->rax);
376             break;
377         case 1:
378             reg->operand = (addr_t)&(gprs->rcx);
379             break;
380         case 2:
381             reg->operand = (addr_t)&(gprs->rdx);
382             break;
383         case 3:
384             reg->operand = (addr_t)&(gprs->rbx);
385             break;
386         case 4:
387             if (reg->size == 1) {
388                 reg->operand = (addr_t)&(gprs->rax) + 1;
389             } else {
390                 reg->operand = (addr_t)&(gprs->rsp);
391             }
392             break;
393         case 5:
394             if (reg->size == 1) {
395                 reg->operand = (addr_t)&(gprs->rcx) + 1;
396             } else {
397                 reg->operand = (addr_t)&(gprs->rbp);
398             }
399             break;
400         case 6:
401             if (reg->size == 1) {
402                 reg->operand = (addr_t)&(gprs->rdx) + 1;
403             } else {
404                 reg->operand = (addr_t)&(gprs->rsi);
405             }
406             break;
407         case 7:
408             if (reg->size == 1) {
409                 reg->operand = (addr_t)&(gprs->rbx) + 1;
410             } else {
411                 reg->operand = (addr_t)&(gprs->rdi);
412             }
413             break;
414         case 8:
415             reg->operand = (addr_t)&(gprs->r8);
416             break;
417         case 9:
418             reg->operand = (addr_t)&(gprs->r9);
419             break;
420         case 10:
421             reg->operand = (addr_t)&(gprs->r10);
422             break;
423         case 11:
424             reg->operand = (addr_t)&(gprs->r11);
425             break;
426         case 12:
427             reg->operand = (addr_t)&(gprs->r12);
428             break;
429         case 13:
430             reg->operand = (addr_t)&(gprs->r13);
431             break;
432         case 14:
433             reg->operand = (addr_t)&(gprs->r14);
434             break;
435         case 15:
436             reg->operand = (addr_t)&(gprs->r15);
437             break;
438         default:
439             PrintError("Invalid Reg Code (%d)\n", reg_code);
440             reg->operand = 0;
441             return -1;
442     }
443
444     return 0;
445 }
446
447
448
449
450 static inline int decode_cr(struct guest_info * core,                   
451                              uint8_t reg_code,
452                              struct x86_operand * reg) {
453
454     struct v3_ctrl_regs * crs = &(core->ctrl_regs);
455
456 //    PrintDebug("\t Ctrl regs %d\n", reg_code);
457
458     switch (reg_code) {
459         case 0:
460             reg->operand = (addr_t)&(crs->cr0);
461             break;
462         case 2:
463             reg->operand = (addr_t)&(crs->cr2);
464             break;
465         case 3:
466             reg->operand = (addr_t)&(crs->cr3);
467             break;
468         case 4:
469             reg->operand = (addr_t)&(crs->cr4);
470             break;
471         default:
472             reg->operand = 0;
473             PrintError("Invalid Reg Code (%d)\n", reg_code);
474             return -1;
475     }
476
477     return 0;
478 }
479
480
481
482 #define ADDR_MASK(val, length) ({                             \
483             ullong_t mask = 0x0LL;                            \
484             switch (length) {                                 \
485                 case 2:                                       \
486                     mask = 0x00000000000fffffLL;              \
487                     break;                                    \
488                 case 4:                                       \
489                     mask = 0x00000000ffffffffLL;              \
490                     break;                                    \
491                 case 8:                                       \
492                     mask = 0xffffffffffffffffLL;              \
493                     break;                                    \
494             }                                                 \
495             val & mask;                                       \
496         })
497
498
499
500 static  int decode_rm_operand16(struct guest_info * core,
501                                 uint8_t * modrm_instr, 
502                                 struct x86_instr * instr,
503                                 struct x86_operand * operand, 
504                                 uint8_t * reg_code) { 
505
506     struct v3_gprs * gprs = &(core->vm_regs);
507     struct modrm_byte * modrm = (struct modrm_byte *)modrm_instr;
508     addr_t base_addr = 0;
509     modrm_mode_t mod_mode = 0;
510     uint8_t * instr_cursor = modrm_instr;
511
512     //  PrintDebug("ModRM mod=%d\n", modrm->mod);
513     
514     *reg_code = modrm->reg;
515
516     instr_cursor += 1;
517
518     if (modrm->mod == 3) {
519         //PrintDebug("first operand = Register (RM=%d)\n",modrm->rm);
520         operand->type = REG_OPERAND;
521
522         decode_gpr(core, modrm->rm, operand);
523
524     } else {
525         struct v3_segment * seg = NULL;
526
527         operand->type = MEM_OPERAND;
528
529         if (modrm->mod == 0) {
530             mod_mode = DISP0;
531         } else if (modrm->mod == 1) {
532             mod_mode = DISP8;
533         } else if (modrm->mod == 2) {
534             mod_mode = DISP16;
535         } else {
536             PrintError("Instruction format error: Invalid mod_rm mode (%d)\n", modrm->mod);
537             v3_print_instr(instr);
538             return -1;
539         }
540
541         switch (modrm->rm) {
542             case 0:
543                 base_addr = gprs->rbx + ADDR_MASK(gprs->rsi, 2);
544                 break;
545             case 1:
546                 base_addr = gprs->rbx + ADDR_MASK(gprs->rdi, 2);
547                 break;
548             case 2:
549                 base_addr = gprs->rbp + ADDR_MASK(gprs->rsi, 2);
550                 break;
551             case 3:
552                 base_addr = gprs->rbp + ADDR_MASK(gprs->rdi, 2);
553                 break;
554             case 4:
555                 base_addr = ADDR_MASK(gprs->rsi, 2);
556                 break;
557             case 5:
558                 base_addr = ADDR_MASK(gprs->rdi, 2);
559                 break;
560             case 6:
561                 if (modrm->mod == 0) {
562                     base_addr = 0;
563                     mod_mode = DISP16;
564                 } else {
565                     base_addr = ADDR_MASK(gprs->rbp, 2);
566                 }
567                 break;
568             case 7:
569                 base_addr = ADDR_MASK(gprs->rbx, 2);
570                 break;
571         }
572
573
574
575         if (mod_mode == DISP8) {
576             base_addr += *(sint8_t *)instr_cursor;
577             instr_cursor += 1;
578         } else if (mod_mode == DISP16) {
579             base_addr += *(sint16_t *)instr_cursor;
580             instr_cursor += 2;
581         }
582     
583         
584         // get appropriate segment
585         if (instr->prefixes.cs_override) {
586             seg = &(core->segments.cs);
587         } else if (instr->prefixes.es_override) {
588             seg = &(core->segments.es);
589         } else if (instr->prefixes.ss_override) {
590             seg = &(core->segments.ss);
591         } else if (instr->prefixes.fs_override) {
592             seg = &(core->segments.fs);
593         } else if (instr->prefixes.gs_override) {
594             seg = &(core->segments.gs);
595         } else {
596             seg = &(core->segments.ds);
597         }
598         
599         operand->operand = ADDR_MASK(get_addr_linear(core, base_addr, seg), 
600                                      get_addr_width(core, instr));
601     }
602
603
604     return (instr_cursor - modrm_instr);
605 }
606
607
608 // returns num_bytes parsed
609 static int decode_rm_operand32(struct guest_info * core, 
610                                uint8_t * modrm_instr,  
611                                struct x86_instr * instr,
612                                struct x86_operand * operand, 
613                                uint8_t * reg_code) {
614
615     struct v3_gprs * gprs = &(core->vm_regs);
616     uint8_t * instr_cursor = modrm_instr;
617     struct modrm_byte * modrm = (struct modrm_byte *)modrm_instr;
618     addr_t base_addr = 0;
619     modrm_mode_t mod_mode = 0;
620     uint_t has_sib_byte = 0;
621
622
623     *reg_code = modrm->reg;
624
625     instr_cursor += 1;
626
627     if (modrm->mod == 3) {
628         operand->type = REG_OPERAND;
629         //    PrintDebug("first operand = Register (RM=%d)\n",modrm->rm);
630
631         decode_gpr(core, modrm->rm, operand);
632
633     } else {
634         struct v3_segment * seg = NULL;
635
636         operand->type = MEM_OPERAND;
637
638         if (modrm->mod == 0) {
639             mod_mode = DISP0;
640         } else if (modrm->mod == 1) {
641             mod_mode = DISP8;
642         } else if (modrm->mod == 2) {
643             mod_mode = DISP32;
644         } else {
645             PrintError("Instruction format error: Invalid mod_rm mode (%d)\n", modrm->mod);
646             v3_print_instr(instr);
647             return -1;
648         }
649     
650         switch (modrm->rm) {
651             case 0:
652                 base_addr = gprs->rax;
653                 break;
654             case 1:
655                 base_addr = gprs->rcx;
656                 break;
657             case 2:
658                 base_addr = gprs->rdx;
659                 break;
660             case 3:
661                 base_addr = gprs->rbx;
662                 break;
663             case 4:
664                 has_sib_byte = 1;
665                 break;
666             case 5:
667                 if (modrm->mod == 0) {
668                     base_addr = 0;
669                     mod_mode = DISP32;
670                 } else {
671                     base_addr = gprs->rbp;
672                 }
673                 break;
674             case 6:
675                 base_addr = gprs->rsi;
676                 break;
677             case 7:
678                 base_addr = gprs->rdi;
679                 break;
680         }
681
682         if (has_sib_byte) {
683             instr_cursor += 1;
684             struct sib_byte * sib = (struct sib_byte *)(instr_cursor);
685             int scale = 0x1 << sib->scale;
686
687             instr_cursor += 1;
688
689             switch (sib->index) {
690                 case 0:
691                     base_addr = gprs->rax;
692                     break;
693                 case 1:
694                     base_addr = gprs->rcx;
695                     break;
696                 case 2:
697                     base_addr = gprs->rdx;
698                     break;
699                 case 3:
700                     base_addr = gprs->rbx;
701                     break;
702                 case 4:
703                     base_addr = 0;
704                     break;
705                 case 5:
706                     base_addr = gprs->rbp;
707                     break;
708                 case 6:
709                     base_addr = gprs->rsi;
710                     break;
711                 case 7:
712                     base_addr = gprs->rdi;
713                     break;
714             }
715
716             base_addr *= scale;
717
718
719             switch (sib->base) {
720                 case 0:
721                     base_addr += ADDR_MASK(gprs->rax, 4);
722                     break;
723                 case 1:
724                     base_addr += ADDR_MASK(gprs->rcx, 4);
725                     break;
726                 case 2:
727                     base_addr += ADDR_MASK(gprs->rdx, 4);
728                     break;
729                 case 3:
730                     base_addr += ADDR_MASK(gprs->rbx, 4);
731                     break;
732                 case 4:
733                     base_addr += ADDR_MASK(gprs->rsp, 4);
734                     break;
735                 case 5:
736                     if (modrm->mod != 0) {
737                         base_addr += ADDR_MASK(gprs->rbp, 4);
738                     }
739                     break;
740                 case 6:
741                     base_addr += ADDR_MASK(gprs->rsi, 4);
742                     break;
743                 case 7:
744                     base_addr += ADDR_MASK(gprs->rdi, 4);
745                     break;
746             }
747
748         } 
749
750
751         if (mod_mode == DISP8) {
752             base_addr += *(sint8_t *)instr_cursor;
753             instr_cursor += 1;
754         } else if (mod_mode == DISP32) {
755             base_addr += *(sint32_t *)instr_cursor;
756             instr_cursor += 4;
757         }
758     
759         // get appropriate segment
760         if (instr->prefixes.cs_override) {
761             seg = &(core->segments.cs);
762         } else if (instr->prefixes.es_override) {
763             seg = &(core->segments.es);
764         } else if (instr->prefixes.ss_override) {
765             seg = &(core->segments.ss);
766         } else if (instr->prefixes.fs_override) {
767             seg = &(core->segments.fs);
768         } else if (instr->prefixes.gs_override) {
769             seg = &(core->segments.gs);
770         } else {
771             seg = &(core->segments.ds);
772         }
773         
774         operand->operand = ADDR_MASK(get_addr_linear(core, base_addr, seg), 
775                                      get_addr_width(core, instr));
776     }
777
778
779     return (instr_cursor - modrm_instr);
780 }
781
782
783 int decode_rm_operand64(struct guest_info * core, uint8_t * modrm_instr, 
784                         struct x86_instr * instr, struct x86_operand * operand, 
785                         uint8_t * reg_code) {
786     
787     struct v3_gprs * gprs = &(core->vm_regs);
788     uint8_t * instr_cursor = modrm_instr;
789     struct modrm_byte * modrm = (struct modrm_byte *)modrm_instr;
790     addr_t base_addr = 0;
791     modrm_mode_t mod_mode = 0;
792     uint_t has_sib_byte = 0;
793
794
795     instr_cursor += 1;
796
797     *reg_code = modrm->reg;
798     *reg_code |= (instr->prefixes.rex_reg << 3);
799
800     if (modrm->mod == 3) {
801         uint8_t rm_val = modrm->rm;
802         
803         rm_val |= (instr->prefixes.rex_rm << 3);
804         
805         operand->type = REG_OPERAND;
806         //    PrintDebug("first operand = Register (RM=%d)\n",modrm->rm);
807         
808         decode_gpr(core, rm_val, operand);
809     } else {
810         struct v3_segment * seg = NULL;
811         uint8_t rm_val = modrm->rm;
812
813         operand->type = MEM_OPERAND;
814
815
816         if (modrm->mod == 0) {
817             mod_mode = DISP0;
818         } else if (modrm->mod == 1) {
819             mod_mode = DISP8;
820         } else if (modrm->mod == 2) {
821             mod_mode = DISP32;
822         } else {
823             PrintError("Instruction format error: Invalid mod_rm mode (%d)\n", modrm->mod);
824             v3_print_instr(instr);
825             return -1;
826         }
827     
828         if (rm_val == 4) {
829             has_sib_byte = 1;
830         } else {
831             rm_val |= (instr->prefixes.rex_rm << 3);
832             
833             switch (rm_val) {
834                 case 0:
835                     base_addr = gprs->rax;
836                     break;
837                 case 1:
838                     base_addr = gprs->rcx;
839                     break;
840                 case 2:
841                     base_addr = gprs->rdx;
842                     break;
843                 case 3:
844                     base_addr = gprs->rbx;
845                     break;
846                 case 5:
847                     if (modrm->mod == 0) {
848                         base_addr = 0;
849                         mod_mode = DISP32;
850                     } else {
851                         base_addr = gprs->rbp;
852                     }
853                     break;
854                 case 6:
855                     base_addr = gprs->rsi;
856                     break;
857                 case 7:
858                     base_addr = gprs->rdi;
859                     break;
860                 case 8:
861                     base_addr = gprs->r8;
862                     break;
863                 case 9:
864                     base_addr = gprs->r9;
865                     break;
866                 case 10:
867                     base_addr = gprs->r10;
868                     break;
869                 case 11:
870                     base_addr = gprs->r11;
871                     break;
872                 case 12:
873                     base_addr = gprs->r12;
874                     break;
875                 case 13:
876                     base_addr = gprs->r13;
877                     break;
878                 case 14:
879                     base_addr = gprs->r14;
880                     break;
881                 case 15:
882                     base_addr = gprs->r15;
883                     break;
884                 default:
885                     return -1;
886             }
887         }
888
889         if (has_sib_byte) {
890             instr_cursor += 1;
891             struct sib_byte * sib = (struct sib_byte *)(instr_cursor);
892             int scale = 0x1 << sib->scale;
893             uint8_t index_val = sib->index;
894             uint8_t base_val = sib->base;
895
896             index_val |= (instr->prefixes.rex_sib_idx << 3);
897             base_val |= (instr->prefixes.rex_rm << 3);
898
899             instr_cursor += 1;
900
901             switch (index_val) {
902                 case 0:
903                     base_addr = gprs->rax;
904                     break;
905                 case 1:
906                     base_addr = gprs->rcx;
907                     break;
908                 case 2:
909                     base_addr = gprs->rdx;
910                     break;
911                 case 3:
912                     base_addr = gprs->rbx;
913                     break;
914                 case 4:
915                     base_addr = 0;
916                     break;
917                 case 5:
918                     base_addr = gprs->rbp;
919                     break;
920                 case 6:
921                     base_addr = gprs->rsi;
922                     break;
923                 case 7:
924                     base_addr = gprs->rdi;
925                     break;
926                 case 8:
927                     base_addr = gprs->r8;
928                     break;
929                 case 9:
930                     base_addr = gprs->r9;
931                     break;
932                 case 10:
933                     base_addr = gprs->r10;
934                     break;
935                 case 11:
936                     base_addr = gprs->r11;
937                     break;
938                 case 12:
939                     base_addr = gprs->r12;
940                     break;
941                 case 13:
942                     base_addr = gprs->r13;
943                     break;
944                 case 14:
945                     base_addr = gprs->r14;
946                     break;
947                 case 15:
948                     base_addr = gprs->r15;
949                     break;
950             }
951
952             base_addr *= scale;
953
954
955             switch (base_val) {
956                 case 0:
957                     base_addr += gprs->rax;
958                     break;
959                 case 1:
960                     base_addr += gprs->rcx;
961                     break;
962                 case 2:
963                     base_addr += gprs->rdx;
964                     break;
965                 case 3:
966                     base_addr += gprs->rbx;
967                     break;
968                 case 4:
969                     base_addr += gprs->rsp;
970                     break;
971                 case 5:
972                     if (modrm->mod != 0) {
973                         base_addr += gprs->rbp;
974                     }
975                     break;
976                 case 6:
977                     base_addr += gprs->rsi;
978                     break;
979                 case 7:
980                     base_addr += gprs->rdi;
981                     break;
982                 case 8:
983                     base_addr += gprs->r8;
984                     break;
985                 case 9:
986                     base_addr += gprs->r9;
987                     break;
988                 case 10:
989                     base_addr += gprs->r10;
990                     break;
991                 case 11:
992                     base_addr += gprs->r11;
993                     break;
994                 case 12:
995                     base_addr += gprs->r12;
996                     break;
997                 case 13:
998                     base_addr += gprs->r13;
999                     break;
1000                 case 14:
1001                     base_addr += gprs->r14;
1002                     break;
1003                 case 15:
1004                     base_addr += gprs->r15;
1005                     break;
1006             }
1007
1008         } 
1009
1010
1011         if (mod_mode == DISP8) {
1012             base_addr += *(sint8_t *)instr_cursor;
1013             instr_cursor += 1;
1014         } else if (mod_mode == DISP32) {
1015             base_addr += *(sint32_t *)instr_cursor;
1016             instr_cursor += 4;
1017         }
1018     
1019
1020         
1021         //Segments should be ignored 
1022         // get appropriate segment
1023
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) {
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         case 0xcd:
1337                 return INT;
1338
1339         case 0xf6: {
1340             struct modrm_byte * modrm = (struct modrm_byte *)&(instr[1]);
1341
1342             switch (modrm->reg) {
1343                 case 2:
1344                     return NOT_8;
1345                 case 3:
1346                     return NEG_8;
1347                 default:
1348                     return INVALID_INSTR;
1349             }
1350         }
1351         case 0xf7: {
1352             struct modrm_byte * modrm = (struct modrm_byte *)&(instr[1]);
1353
1354             switch (modrm->reg) {
1355                 case 2:
1356                     return NOT;
1357                 case 3:
1358                     return NEG;
1359                 default:
1360                     return INVALID_INSTR;
1361             }
1362         }
1363             
1364
1365         case 0xfe: {
1366             struct modrm_byte * modrm = (struct modrm_byte *)&(instr[1]);
1367
1368             switch (modrm->reg) {
1369                 case 0:
1370                     return INC_8;
1371                 case 1:
1372                     return DEC_8;
1373                 default:
1374                     return INVALID_INSTR;
1375             }
1376         }
1377
1378         case 0xff: {
1379             struct modrm_byte * modrm = (struct modrm_byte *)&(instr[1]);
1380
1381             switch (modrm->reg) {
1382                 case 0:
1383                     return INC;
1384                 case 1:
1385                     return DEC;
1386                 default:
1387                     return INVALID_INSTR;
1388             }
1389         }
1390
1391         default:
1392             return INVALID_INSTR;
1393     }
1394 }
1395
1396
1397
1398 static char * op_form_to_str(op_form_t form) {
1399
1400     switch (form) {
1401         case LMSW: return "LMSW";
1402         case SMSW: return "SMSW";
1403         case CLTS: return "CLTS";
1404         case INVLPG: return "INVLPG";
1405         case MOV_CR2: return "MOV_CR2";
1406         case MOV_2CR: return "MOV_2CR";
1407         case MOV_DR2: return "MOV_DR2";
1408         case MOV_2DR: return "MOV_2DR";
1409         case MOV_SR2: return "MOV_SR2";
1410         case MOV_2SR: return "MOV_2SR";
1411         case MOV_MEM2_8: return "MOV_MEM2_8";
1412         case MOV_MEM2: return "MOV_MEM2";
1413         case MOV_2MEM_8: return "MOV_2MEM_8";
1414         case MOV_2MEM: return "MOV_2MEM";
1415         case MOV_MEM2AL_8: return "MOV_MEM2AL_8";
1416         case MOV_MEM2AX: return "MOV_MEM2AX";
1417         case MOV_AL2MEM_8: return "MOV_AL2MEM_8";
1418         case MOV_AX2MEM: return "MOV_AX2MEM";
1419         case MOV_IMM2_8: return "MOV_IMM2_8";
1420         case MOV_IMM2: return "MOV_IMM2";
1421         case MOVS_8: return "MOVS_8";
1422         case MOVS: return "MOVS";
1423         case MOVSX_8: return "MOVSX_8";
1424         case MOVSX: return "MOVSX";
1425         case MOVZX_8: return "MOVZX_8";
1426         case MOVZX: return "MOVZX";
1427         case HLT: return "HLT";
1428         case PUSHF: return "PUSHF";
1429         case POPF: return "POPF";
1430         case ADC_2MEM_8: return "ADC_2MEM_8";
1431         case ADC_2MEM: return "ADC_2MEM";
1432         case ADC_MEM2_8: return "ADC_MEM2_8";
1433         case ADC_MEM2: return "ADC_MEM2";
1434         case ADC_IMM2_8: return "ADC_IMM2_8";
1435         case ADC_IMM2: return "ADC_IMM2";
1436         case ADC_IMM2SX_8: return "ADC_IMM2SX_8";
1437         case ADD_IMM2_8: return "ADD_IMM2_8";
1438         case ADD_IMM2: return "ADD_IMM2";
1439         case ADD_IMM2SX_8: return "ADD_IMM2SX_8";
1440         case ADD_2MEM_8: return "ADD_2MEM_8";
1441         case ADD_2MEM: return "ADD_2MEM";
1442         case ADD_MEM2_8: return "ADD_MEM2_8";
1443         case ADD_MEM2: return "ADD_MEM2";
1444         case AND_MEM2_8: return "AND_MEM2_8";
1445         case AND_MEM2: return "AND_MEM2";
1446         case AND_2MEM_8: return "AND_2MEM_8";
1447         case AND_2MEM: return "AND_2MEM";
1448         case AND_IMM2_8: return "AND_IMM2_8";
1449         case AND_IMM2: return "AND_IMM2";
1450         case AND_IMM2SX_8: return "AND_IMM2SX_8";
1451         case OR_2MEM_8: return "OR_2MEM_8";
1452         case OR_2MEM: return "OR_2MEM";
1453         case OR_MEM2_8: return "OR_MEM2_8";
1454         case OR_MEM2: return "OR_MEM2";
1455         case OR_IMM2_8: return "OR_IMM2_8";
1456         case OR_IMM2: return "OR_IMM2";
1457         case OR_IMM2SX_8: return "OR_IMM2SX_8";
1458         case SUB_2MEM_8: return "SUB_2MEM_8";
1459         case SUB_2MEM: return "SUB_2MEM";
1460         case SUB_MEM2_8: return "SUB_MEM2_8";
1461         case SUB_MEM2: return "SUB_MEM2";
1462         case SUB_IMM2_8: return "SUB_IMM2_8";
1463         case SUB_IMM2: return "SUB_IMM2";
1464         case SUB_IMM2SX_8: return "SUB_IMM2SX_8";
1465         case XOR_2MEM_8: return "XOR_2MEM_8";
1466         case XOR_2MEM: return "XOR_2MEM";
1467         case XOR_MEM2_8: return "XOR_MEM2_8";
1468         case XOR_MEM2: return "XOR_MEM2";
1469         case XOR_IMM2_8: return "XOR_IMM2_8";
1470         case XOR_IMM2: return "XOR_IMM2";
1471         case XOR_IMM2SX_8: return "XOR_IMM2SX_8";
1472         case INC_8: return "INC_8";
1473         case INC: return "INC";
1474         case DEC_8: return "DEC_8";
1475         case DEC: return "DEC";
1476         case NEG_8: return "NEG_8";
1477         case NEG: return "NEG"; 
1478         case NOT_8: return "NOT_8";
1479         case NOT: return "NOT";
1480         case XCHG_8: return "XCHG_8";
1481         case XCHG: return "XCHG";
1482         case SETB: return "SETB";
1483         case SETBE: return "SETBE";
1484         case SETL: return "SETL";
1485         case SETLE: return "SETLE";
1486         case SETNB: return "SETNB";
1487         case SETNBE: return "SETNBE";
1488         case SETNL: return "SETNL";
1489         case SETNLE: return "SETNLE";
1490         case SETNO: return "SETNO";
1491         case SETNP: return "SETNP";
1492         case SETNS: return "SETNS";
1493         case SETNZ: return "SETNZ";
1494         case SETP: return "SETP";
1495         case SETS: return "SETS";
1496         case SETZ: return "SETZ";
1497         case SETO: return "SETO";
1498         case STOS_8: return "STOS_8";
1499         case STOS: return "STOS";
1500         case INT: return "INT";
1501
1502         case INVALID_INSTR:
1503         default:
1504             return "INVALID_INSTR";
1505     }
1506 }