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.


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