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.


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