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.


Basic HVM data structures and functions
[palacios.git] / palacios / include / palacios / vmm_instr_decoder.h
1 /*
2  * This file is part of the Palacios Virtual Machine Monitor developed
3  * by the V3VEE Project with funding from the United States National 
4  * Science Foundation and the Department of Energy.  
5  *
6  * The V3VEE Project is a joint project between Northwestern University
7  * and the University of New Mexico.  You can find out more at 
8  * http://www.v3vee.org
9  *
10  * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu> 
11  * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org> 
12  * All rights reserved.
13  *
14  * Author: Jack Lange <jarusl@cs.northwestern.edu>
15  *
16  * This is free software.  You are permitted to use,
17  * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
18  */
19
20 #include <palacios/vmm_types.h>
21
22 /* .... Giant fucking switch tables */
23
24
25 typedef enum {
26     INVALID_INSTR,
27     LMSW,
28     SMSW,
29     CLTS,
30     INVLPG,
31     INT, 
32
33     MOV_CR2,
34     MOV_2CR,
35     MOV_DR2,
36     MOV_2DR,
37     MOV_SR2,
38     MOV_2SR,
39
40     MOV_MEM2_8,
41     MOV_MEM2,
42     MOV_2MEM_8,
43     MOV_2MEM,
44     MOV_MEM2AL_8,
45     MOV_MEM2AX,
46     MOV_AL2MEM_8,
47     MOV_AX2MEM,
48     MOV_IMM2_8,
49     MOV_IMM2,
50
51     MOVS_8,
52     MOVS,
53     MOVSX_8,
54     MOVSX,
55     MOVZX_8,
56     MOVZX,
57
58     HLT,
59     PUSHF,
60     POPF,
61
62     ADC_2MEM_8,
63     ADC_2MEM,
64     ADC_MEM2_8,
65     ADC_MEM2,
66     ADC_IMM2_8,
67     ADC_IMM2,
68     ADC_IMM2SX_8,
69     ADD_IMM2_8,
70     ADD_IMM2,
71     ADD_IMM2SX_8,
72     ADD_2MEM_8,
73     ADD_2MEM,
74     ADD_MEM2_8,
75     ADD_MEM2,
76     AND_MEM2_8,
77     AND_MEM2,
78     AND_2MEM_8,
79     AND_2MEM,
80     AND_IMM2_8,
81     AND_IMM2,
82     AND_IMM2SX_8,
83     OR_2MEM_8,
84     OR_2MEM,
85     OR_MEM2_8,
86     OR_MEM2,
87     OR_IMM2_8,
88     OR_IMM2,
89     OR_IMM2SX_8,
90     SUB_2MEM_8,
91     SUB_2MEM,
92     SUB_MEM2_8,
93     SUB_MEM2,
94     SUB_IMM2_8,
95     SUB_IMM2,
96     SUB_IMM2SX_8,
97     XOR_2MEM_8,
98     XOR_2MEM,
99     XOR_MEM2_8,
100     XOR_MEM2,
101     XOR_IMM2_8,
102     XOR_IMM2,
103     XOR_IMM2SX_8,
104
105     INC_8,
106     INC,
107     DEC_8,
108     DEC,
109     NEG_8,
110     NEG, 
111     NOT_8,
112     NOT,
113     XCHG_8,
114     XCHG,
115
116     SETB,
117     SETBE,
118     SETL,
119     SETLE,
120     SETNB,
121     SETNBE,
122     SETNL,
123     SETNLE,
124     SETNO,
125     SETNP,
126     SETNS,
127     SETNZ,
128     SETP,
129     SETS,
130     SETZ,
131     SETO,
132
133     STOS_8,
134     STOS
135 } op_form_t;
136
137
138 static int get_addr_width(struct guest_info * info, struct x86_instr * instr) {
139
140     switch (v3_get_vm_cpu_mode(info)) {
141         case REAL:
142             return (instr->prefixes.addr_size) ? 4 : 2;
143         case LONG:
144                 return 8;
145         case PROTECTED:
146         case PROTECTED_PAE:
147         case LONG_32_COMPAT:
148                 if (info->segments.cs.db) {
149                         return (instr->prefixes.addr_size) ? 2 : 4;
150                 } else {
151                         return (instr->prefixes.addr_size) ? 4 : 2;
152                 }                       
153         default:
154             PrintError(info->vm_info, info, "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 INT:
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 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         case MOV_IMM2:
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                     } else {
267                         return (instr->prefixes.op_size) ? 2 : 4;
268                     }
269                 case PROTECTED:
270                 case PROTECTED_PAE:
271                 case LONG_32_COMPAT:
272                     if (info->segments.cs.db) {
273                         // default is 32
274                         return (instr->prefixes.op_size) ? 2 : 4;
275                     } else {
276                         return (instr->prefixes.op_size) ? 4 : 2;
277                     }
278                 default:
279                     PrintError(info->vm_info, info, "Unsupported CPU mode: %d\n", info->cpu_mode);
280                     return -1;
281             }
282         case INVLPG:
283             switch (v3_get_vm_cpu_mode(info)) {
284                 case REAL:
285                     PrintError(info->vm_info, info, "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(info->vm_info, info, "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(info->vm_info, info, "Unsupported CPU mode: %d\n", info->cpu_mode);
311                     return -1;
312             }
313
314         //case INT:
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(info->vm_info, info, "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(info->vm_info, info, "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(core->vm_info, core, "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(core->vm_info, core, "\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(core->vm_info, core, "Invalid Reg Code (%d)\n", reg_code);
475             return -1;
476     }
477
478     return 0;
479 }
480
481 static struct v3_segment * get_instr_segment(struct guest_info * core, struct x86_instr * instr) {
482     struct v3_segment * seg = &(core->segments.ds);
483
484     if (instr->prefixes.cs_override) {
485         seg = &(core->segments.cs);
486     } else if (instr->prefixes.es_override) {
487         seg = &(core->segments.es);
488     } else if (instr->prefixes.ss_override) {
489         seg = &(core->segments.ss);
490     } else if (instr->prefixes.fs_override) {
491         seg = &(core->segments.fs);
492     } else if (instr->prefixes.gs_override) {
493         seg = &(core->segments.gs);
494     } 
495
496     return seg;
497 }
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(core->vm_info, core, "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(core->vm_info, core, "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         } else {
555             PrintError(core->vm_info, core, "Instruction format error: Invalid mod_rm mode (%d)\n", modrm->mod);
556             v3_print_instr(instr);
557             return -1;
558         }
559
560         switch (modrm->rm) {
561             case 0:
562                 base_addr = gprs->rbx + ADDR_MASK(gprs->rsi, 2);
563                 break;
564             case 1:
565                 base_addr = gprs->rbx + ADDR_MASK(gprs->rdi, 2);
566                 break;
567             case 2:
568                 base_addr = gprs->rbp + ADDR_MASK(gprs->rsi, 2);
569                 break;
570             case 3:
571                 base_addr = gprs->rbp + ADDR_MASK(gprs->rdi, 2);
572                 break;
573             case 4:
574                 base_addr = ADDR_MASK(gprs->rsi, 2);
575                 break;
576             case 5:
577                 base_addr = ADDR_MASK(gprs->rdi, 2);
578                 break;
579             case 6:
580                 if (modrm->mod == 0) {
581                     base_addr = 0;
582                     mod_mode = DISP16;
583                 } else {
584                     base_addr = ADDR_MASK(gprs->rbp, 2);
585                 }
586                 break;
587             case 7:
588                 base_addr = ADDR_MASK(gprs->rbx, 2);
589                 break;
590         }
591
592
593
594         if (mod_mode == DISP8) {
595             base_addr += *(sint8_t *)instr_cursor;
596             instr_cursor += 1;
597         } else if (mod_mode == DISP16) {
598             base_addr += *(sint16_t *)instr_cursor;
599             instr_cursor += 2;
600         }
601     
602         
603         // get appropriate segment
604         if (instr->prefixes.cs_override) {
605             seg = &(core->segments.cs);
606         } else if (instr->prefixes.es_override) {
607             seg = &(core->segments.es);
608         } else if (instr->prefixes.ss_override) {
609             seg = &(core->segments.ss);
610         } else if (instr->prefixes.fs_override) {
611             seg = &(core->segments.fs);
612         } else if (instr->prefixes.gs_override) {
613             seg = &(core->segments.gs);
614         } else {
615             seg = &(core->segments.ds);
616         }
617         
618         operand->operand = ADDR_MASK(get_addr_linear(core, base_addr, seg), 
619                                      get_addr_width(core, instr));
620     }
621
622
623     return (instr_cursor - modrm_instr);
624 }
625
626
627 // returns num_bytes parsed
628 static int decode_rm_operand32(struct guest_info * core, 
629                                uint8_t * modrm_instr,  
630                                struct x86_instr * instr,
631                                struct x86_operand * operand, 
632                                uint8_t * reg_code) {
633
634     struct v3_gprs * gprs = &(core->vm_regs);
635     uint8_t * instr_cursor = modrm_instr;
636     struct modrm_byte * modrm = (struct modrm_byte *)modrm_instr;
637     addr_t base_addr = 0;
638     modrm_mode_t mod_mode = 0;
639     uint_t has_sib_byte = 0;
640
641
642     *reg_code = modrm->reg;
643
644     instr_cursor += 1;
645
646     if (modrm->mod == 3) {
647         operand->type = REG_OPERAND;
648         //    PrintDebug(core->vm_info, core, "first operand = Register (RM=%d)\n",modrm->rm);
649
650         decode_gpr(core, modrm->rm, operand);
651
652     } else {
653         struct v3_segment * seg = NULL;
654
655         operand->type = MEM_OPERAND;
656
657         if (modrm->mod == 0) {
658             mod_mode = DISP0;
659         } else if (modrm->mod == 1) {
660             mod_mode = DISP8;
661         } else if (modrm->mod == 2) {
662             mod_mode = DISP32;
663         } else {
664             PrintError(core->vm_info, core, "Instruction format error: Invalid mod_rm mode (%d)\n", modrm->mod);
665             v3_print_instr(instr);
666             return -1;
667         }
668     
669         switch (modrm->rm) {
670             case 0:
671                 base_addr = gprs->rax;
672                 break;
673             case 1:
674                 base_addr = gprs->rcx;
675                 break;
676             case 2:
677                 base_addr = gprs->rdx;
678                 break;
679             case 3:
680                 base_addr = gprs->rbx;
681                 break;
682             case 4:
683                 has_sib_byte = 1;
684                 break;
685             case 5:
686                 if (modrm->mod == 0) {
687                     base_addr = 0;
688                     mod_mode = DISP32;
689                 } else {
690                     base_addr = gprs->rbp;
691                 }
692                 break;
693             case 6:
694                 base_addr = gprs->rsi;
695                 break;
696             case 7:
697                 base_addr = gprs->rdi;
698                 break;
699         }
700
701         if (has_sib_byte) {
702             struct sib_byte * sib = (struct sib_byte *)(instr_cursor);
703             int scale = 0x1 << sib->scale;
704
705             instr_cursor += 1;
706
707             switch (sib->index) {
708                 case 0:
709                     base_addr = gprs->rax;
710                     break;
711                 case 1:
712                     base_addr = gprs->rcx;
713                     break;
714                 case 2:
715                     base_addr = gprs->rdx;
716                     break;
717                 case 3:
718                     base_addr = gprs->rbx;
719                     break;
720                 case 4:
721                     base_addr = 0;
722                     break;
723                 case 5:
724                     base_addr = gprs->rbp;
725                     break;
726                 case 6:
727                     base_addr = gprs->rsi;
728                     break;
729                 case 7:
730                     base_addr = gprs->rdi;
731                     break;
732             }
733
734             base_addr *= scale;
735
736
737             switch (sib->base) {
738                 case 0:
739                     base_addr += ADDR_MASK(gprs->rax, 4);
740                     break;
741                 case 1:
742                     base_addr += ADDR_MASK(gprs->rcx, 4);
743                     break;
744                 case 2:
745                     base_addr += ADDR_MASK(gprs->rdx, 4);
746                     break;
747                 case 3:
748                     base_addr += ADDR_MASK(gprs->rbx, 4);
749                     break;
750                 case 4:
751                     base_addr += ADDR_MASK(gprs->rsp, 4);
752                     break;
753                 case 5:
754                     if (modrm->mod != 0) {
755                         base_addr += ADDR_MASK(gprs->rbp, 4);
756                     } else {
757                         mod_mode = DISP32;
758                         base_addr = 0;
759                     }
760                     break;
761                 case 6:
762                     base_addr += ADDR_MASK(gprs->rsi, 4);
763                     break;
764                 case 7:
765                     base_addr += ADDR_MASK(gprs->rdi, 4);
766                     break;
767             }
768
769         } 
770
771
772         if (mod_mode == DISP8) {
773             base_addr += *(sint8_t *)instr_cursor;
774             instr_cursor += 1;
775         } else if (mod_mode == DISP32) {
776             base_addr += *(sint32_t *)instr_cursor;
777             instr_cursor += 4;
778         }
779     
780         // get appropriate segment
781         if (instr->prefixes.cs_override) {
782             seg = &(core->segments.cs);
783         } else if (instr->prefixes.es_override) {
784             seg = &(core->segments.es);
785         } else if (instr->prefixes.ss_override) {
786             seg = &(core->segments.ss);
787         } else if (instr->prefixes.fs_override) {
788             seg = &(core->segments.fs);
789         } else if (instr->prefixes.gs_override) {
790             seg = &(core->segments.gs);
791         } else {
792             seg = &(core->segments.ds);
793         }
794         
795         operand->operand = ADDR_MASK(get_addr_linear(core, base_addr, seg), 
796                                      get_addr_width(core, instr));
797     }
798
799
800     return (instr_cursor - modrm_instr);
801 }
802
803
804 int decode_rm_operand64(struct guest_info * core, uint8_t * modrm_instr, 
805                         struct x86_instr * instr, struct x86_operand * operand, 
806                         uint8_t * reg_code) {
807     
808     struct v3_gprs * gprs = &(core->vm_regs);
809     uint8_t * instr_cursor = modrm_instr;
810     struct modrm_byte * modrm = (struct modrm_byte *)modrm_instr;
811     addr_t base_addr = 0;
812     modrm_mode_t mod_mode = 0;
813     uint_t has_sib_byte = 0;
814
815
816     instr_cursor += 1;
817
818     *reg_code = modrm->reg;
819     *reg_code |= (instr->prefixes.rex_reg << 3);
820
821     if (modrm->mod == 3) {
822         uint8_t rm_val = modrm->rm;
823         
824         rm_val |= (instr->prefixes.rex_rm << 3);
825         
826         operand->type = REG_OPERAND;
827         //    PrintDebug(core->vm_info, core, "first operand = Register (RM=%d)\n",modrm->rm);
828         
829         decode_gpr(core, rm_val, operand);
830     } else {
831         struct v3_segment * seg = NULL;
832         uint8_t rm_val = modrm->rm;
833
834         operand->type = MEM_OPERAND;
835
836
837         if (modrm->mod == 0) {
838             mod_mode = DISP0;
839         } else if (modrm->mod == 1) {
840             mod_mode = DISP8;
841         } else if (modrm->mod == 2) {
842             mod_mode = DISP32;
843         } else {
844             PrintError(core->vm_info, core, "Instruction format error: Invalid mod_rm mode (%d)\n", modrm->mod);
845             v3_print_instr(instr);
846             return -1;
847         }
848     
849         if (rm_val == 4) {
850             has_sib_byte = 1;
851         } else {
852             rm_val |= (instr->prefixes.rex_rm << 3);
853             
854             switch (rm_val) {
855                 case 0:
856                     base_addr = gprs->rax;
857                     break;
858                 case 1:
859                     base_addr = gprs->rcx;
860                     break;
861                 case 2:
862                     base_addr = gprs->rdx;
863                     break;
864                 case 3:
865                     base_addr = gprs->rbx;
866                     break;
867                 case 5:
868                     if (modrm->mod == 0) {
869                         base_addr = 0;
870                         mod_mode = DISP32;
871                     } else {
872                         base_addr = gprs->rbp;
873                     }
874                     break;
875                 case 6:
876                     base_addr = gprs->rsi;
877                     break;
878                 case 7:
879                     base_addr = gprs->rdi;
880                     break;
881                 case 8:
882                     base_addr = gprs->r8;
883                     break;
884                 case 9:
885                     base_addr = gprs->r9;
886                     break;
887                 case 10:
888                     base_addr = gprs->r10;
889                     break;
890                 case 11:
891                     base_addr = gprs->r11;
892                     break;
893                 case 12:
894                     base_addr = gprs->r12;
895                     break;
896                 case 13:
897                     base_addr = gprs->r13;
898                     break;
899                 case 14:
900                     base_addr = gprs->r14;
901                     break;
902                 case 15:
903                     base_addr = gprs->r15;
904                     break;
905                 default:
906                     return -1;
907             }
908         }
909
910         if (has_sib_byte) {
911             struct sib_byte * sib = (struct sib_byte *)(instr_cursor);
912             int scale = 0x1 << sib->scale;
913             uint8_t index_val = sib->index;
914             uint8_t base_val = sib->base;
915
916             index_val |= (instr->prefixes.rex_sib_idx << 3);
917             base_val |= (instr->prefixes.rex_rm << 3);
918
919             instr_cursor += 1;
920
921             switch (index_val) {
922                 case 0:
923                     base_addr = gprs->rax;
924                     break;
925                 case 1:
926                     base_addr = gprs->rcx;
927                     break;
928                 case 2:
929                     base_addr = gprs->rdx;
930                     break;
931                 case 3:
932                     base_addr = gprs->rbx;
933                     break;
934                 case 4:
935                     base_addr = 0;
936                     break;
937                 case 5:
938                     base_addr = gprs->rbp;
939                     break;
940                 case 6:
941                     base_addr = gprs->rsi;
942                     break;
943                 case 7:
944                     base_addr = gprs->rdi;
945                     break;
946                 case 8:
947                     base_addr = gprs->r8;
948                     break;
949                 case 9:
950                     base_addr = gprs->r9;
951                     break;
952                 case 10:
953                     base_addr = gprs->r10;
954                     break;
955                 case 11:
956                     base_addr = gprs->r11;
957                     break;
958                 case 12:
959                     base_addr = gprs->r12;
960                     break;
961                 case 13:
962                     base_addr = gprs->r13;
963                     break;
964                 case 14:
965                     base_addr = gprs->r14;
966                     break;
967                 case 15:
968                     base_addr = gprs->r15;
969                     break;
970             }
971
972             base_addr *= scale;
973
974
975             switch (base_val) {
976                 case 0:
977                     base_addr += gprs->rax;
978                     break;
979                 case 1:
980                     base_addr += gprs->rcx;
981                     break;
982                 case 2:
983                     base_addr += gprs->rdx;
984                     break;
985                 case 3:
986                     base_addr += gprs->rbx;
987                     break;
988                 case 4:
989                     base_addr += gprs->rsp;
990                     break;
991                 case 5:
992                     if (modrm->mod != 0) {
993                         base_addr += gprs->rbp;
994                     } else {
995                         mod_mode = DISP32;
996                         base_addr = 0;
997                     }
998                     break;
999                 case 6:
1000                     base_addr += gprs->rsi;
1001                     break;
1002                 case 7:
1003                     base_addr += gprs->rdi;
1004                     break;
1005                 case 8:
1006                     base_addr += gprs->r8;
1007                     break;
1008                 case 9:
1009                     base_addr += gprs->r9;
1010                     break;
1011                 case 10:
1012                     base_addr += gprs->r10;
1013                     break;
1014                 case 11:
1015                     base_addr += gprs->r11;
1016                     break;
1017                 case 12:
1018                     base_addr += gprs->r12;
1019                     break;
1020                 case 13:
1021                     base_addr += gprs->r13;
1022                     break;
1023                 case 14:
1024                     base_addr += gprs->r14;
1025                     break;
1026                 case 15:
1027                     base_addr += gprs->r15;
1028                     break;
1029             }
1030
1031         } 
1032
1033
1034         if (mod_mode == DISP8) {
1035             base_addr += *(sint8_t *)instr_cursor;
1036             instr_cursor += 1;
1037         } else if (mod_mode == DISP32) {
1038             base_addr += *(sint32_t *)instr_cursor;
1039             instr_cursor += 4;
1040         }
1041     
1042
1043         
1044         //Segments should be ignored 
1045         // get appropriate segment
1046
1047         if (instr->prefixes.cs_override) {
1048             seg = &(core->segments.cs);
1049         } else if (instr->prefixes.es_override) {
1050             seg = &(core->segments.es);
1051         } else if (instr->prefixes.ss_override) {
1052             seg = &(core->segments.ss);
1053         } else if (instr->prefixes.fs_override) {
1054             seg = &(core->segments.fs);
1055         } else if (instr->prefixes.gs_override) {
1056             seg = &(core->segments.gs);
1057         } else {
1058             seg = &(core->segments.ds);
1059         }
1060         
1061
1062         operand->operand = ADDR_MASK(get_addr_linear(core, base_addr, seg), 
1063                                      get_addr_width(core, instr));
1064     }
1065
1066
1067     return (instr_cursor - modrm_instr);
1068
1069
1070 }
1071
1072
1073 static int decode_rm_operand(struct guest_info * core, 
1074                              uint8_t * instr_ptr,        // input
1075                              op_form_t form, 
1076                              struct x86_instr * instr,
1077                              struct x86_operand * operand, 
1078                              uint8_t * reg_code) {
1079     
1080     v3_cpu_mode_t mode = v3_get_vm_cpu_mode(core);
1081
1082     operand->size = get_operand_width(core, instr, form);
1083
1084     switch (mode) {
1085         case REAL:
1086             return decode_rm_operand16(core, instr_ptr, instr, operand, reg_code);
1087         case LONG:
1088             if (instr->prefixes.rex) {
1089                 return decode_rm_operand64(core, instr_ptr, instr, operand, reg_code);
1090             }
1091         case PROTECTED:
1092         case PROTECTED_PAE:
1093         case LONG_32_COMPAT:
1094             return decode_rm_operand32(core, instr_ptr, instr, operand, reg_code);
1095         default:
1096             PrintError(core->vm_info, core, "Invalid CPU_MODE (%d)\n", mode);
1097             return -1;
1098     }
1099 }
1100                              
1101
1102
1103 static inline op_form_t op_code_to_form_0f(uint8_t * instr, int * length) {
1104     *length += 1;
1105
1106     switch (instr[1]) {
1107         case 0x01: {
1108             struct modrm_byte * modrm = (struct modrm_byte *)&(instr[2]);
1109
1110             switch (modrm->reg) {
1111                 case 4:
1112                     return SMSW;
1113                 case 6:
1114                     return LMSW;
1115                 case 7:
1116                     return INVLPG;
1117                 default:
1118                     return INVALID_INSTR;
1119             }
1120         }
1121
1122         case 0x06:
1123             return CLTS;
1124         case 0x20:
1125             return MOV_CR2;
1126         case 0x21:
1127             return MOV_DR2;
1128
1129         case 0x22:
1130             return MOV_2CR;
1131         case 0x23:
1132             return MOV_2DR;
1133
1134         case 0x90:
1135             return SETO;
1136         case 0x91:
1137             return SETNO;
1138         case 0x92:
1139             return SETB;
1140         case 0x93:
1141             return SETNB;
1142         case 0x94:
1143             return SETZ;
1144         case 0x95:
1145             return SETNZ;
1146         case 0x96:
1147             return SETBE;
1148         case 0x97:
1149             return SETNBE;
1150         case 0x98:
1151             return SETS;
1152         case 0x99:
1153             return SETNS;
1154         case 0x9a:
1155             return SETP;
1156         case 0x9b:
1157             return SETNP;
1158         case 0x9c:
1159             return SETL;
1160         case 0x9d:
1161             return SETNL;
1162         case 0x9e:
1163             return SETLE;
1164         case 0x9f:
1165             return SETNLE;
1166
1167         case 0xb6:
1168             return MOVZX_8;
1169         case 0xb7:
1170             return MOVZX;
1171
1172         case 0xbe:
1173             return MOVSX_8;
1174         case 0xbf:
1175             return MOVSX;
1176             
1177
1178         default:
1179             return INVALID_INSTR;
1180     }
1181 }
1182
1183
1184 static op_form_t op_code_to_form(uint8_t * instr, int * length) {
1185     *length += 1;
1186
1187     switch (instr[0]) {
1188         case 0x00:
1189             return ADD_2MEM_8;
1190         case 0x01:
1191             return ADD_2MEM;
1192         case 0x02:
1193             return ADD_MEM2_8;
1194         case 0x03:
1195             return ADD_MEM2;
1196
1197         case 0x08:
1198             return OR_2MEM_8;
1199         case 0x09:
1200             return OR_2MEM;
1201         case 0x0a:
1202             return OR_MEM2_8;
1203         case 0x0b:
1204             return OR_MEM2;
1205
1206
1207         case 0x0f:
1208             return op_code_to_form_0f(instr, length);
1209
1210         case 0x10:
1211             return ADC_2MEM_8;
1212         case 0x11:
1213             return ADC_2MEM;
1214         case 0x12:
1215             return ADC_MEM2_8;
1216         case 0x13:
1217             return ADC_MEM2;
1218
1219         case 0x20:
1220             return AND_2MEM_8; 
1221         case 0x21:
1222             return AND_2MEM;
1223         case 0x22:
1224             return AND_MEM2_8;
1225         case 0x23:
1226             return AND_MEM2;
1227
1228         case 0x28:
1229             return SUB_2MEM_8;
1230         case 0x29:
1231             return SUB_2MEM;
1232         case 0x2a:
1233             return SUB_MEM2_8;
1234         case 0x2b:
1235             return SUB_MEM2;
1236
1237
1238         case 0x30:
1239             return XOR_2MEM_8;
1240         case 0x31:
1241             return XOR_2MEM;
1242         case 0x32:
1243             return XOR_MEM2_8;
1244         case 0x33:
1245             return XOR_MEM2;
1246
1247         case 0x80:{
1248             struct modrm_byte * modrm = (struct modrm_byte *)&(instr[1]);
1249
1250             switch (modrm->reg) {
1251                 case 0:
1252                     return ADD_IMM2_8;
1253                 case 1:
1254                     return OR_IMM2_8;
1255                 case 2:
1256                     return ADC_IMM2_8;
1257                 case 4:
1258                     return AND_IMM2_8;
1259                 case 5:
1260                     return SUB_IMM2_8;
1261                 case 6:
1262                     return XOR_IMM2_8;
1263                 default:
1264                     return INVALID_INSTR;
1265             }
1266         }
1267         case 0x81: {
1268             struct modrm_byte * modrm = (struct modrm_byte *)&(instr[1]);
1269             
1270             switch (modrm->reg) {
1271                 case 0:
1272                     return ADD_IMM2;
1273                 case 1:
1274                     return OR_IMM2;
1275                 case 2:
1276                     return ADC_IMM2;
1277                 case 4:
1278                     return AND_IMM2;
1279                 case 5:
1280                     return SUB_IMM2;
1281                 case 6:
1282                     return XOR_IMM2;
1283                 default:
1284                     return INVALID_INSTR;
1285             }
1286         }
1287         case 0x83: {
1288             struct modrm_byte * modrm = (struct modrm_byte *)&(instr[1]);
1289
1290             switch (modrm->reg) {
1291                 case 0:
1292                     return ADD_IMM2SX_8;
1293                 case 1:
1294                     return OR_IMM2SX_8;
1295                 case 2:
1296                     return ADC_IMM2SX_8;
1297                 case 4:
1298                     return AND_IMM2SX_8;
1299                 case 5:
1300                     return SUB_IMM2SX_8;
1301                 case 6:
1302                     return XOR_IMM2SX_8;
1303                 default:
1304                     return INVALID_INSTR;
1305             }
1306         }
1307
1308         case 0x86:
1309             return XCHG_8;
1310         case 0x87:
1311             return XCHG;
1312         case 0x88:
1313             return MOV_2MEM_8;
1314         case 0x89:
1315             return MOV_2MEM;
1316         case 0x8a:
1317             return MOV_MEM2_8;
1318         case 0x8b:
1319             return MOV_MEM2;
1320             
1321         case 0x8c:
1322             return MOV_SR2;
1323         case 0x8e:
1324             return MOV_2SR;
1325
1326
1327         case 0x9c:
1328             return PUSHF;
1329         case 0x9d:
1330             return POPF;
1331
1332         case 0xa0:
1333             return MOV_MEM2AL_8;
1334         case 0xa1:
1335             return MOV_MEM2AX;
1336         case 0xa2:
1337             return MOV_AL2MEM_8;
1338         case 0xa3:
1339             return MOV_AX2MEM;
1340
1341         case 0xa4:
1342             return MOVS_8;
1343         case 0xa5:
1344             return MOVS;
1345
1346         case 0xaa:
1347             return STOS_8;
1348         case 0xab:
1349             return STOS;
1350
1351         case 0xc6:
1352             return MOV_IMM2_8;
1353         case 0xc7:
1354             return MOV_IMM2;
1355
1356         case 0xf4:
1357             return HLT;
1358
1359         case 0xcd:
1360                 return INT;
1361
1362         case 0xf6: {
1363             struct modrm_byte * modrm = (struct modrm_byte *)&(instr[1]);
1364
1365             switch (modrm->reg) {
1366                 case 2:
1367                     return NOT_8;
1368                 case 3:
1369                     return NEG_8;
1370                 default:
1371                     return INVALID_INSTR;
1372             }
1373         }
1374         case 0xf7: {
1375             struct modrm_byte * modrm = (struct modrm_byte *)&(instr[1]);
1376
1377             switch (modrm->reg) {
1378                 case 2:
1379                     return NOT;
1380                 case 3:
1381                     return NEG;
1382                 default:
1383                     return INVALID_INSTR;
1384             }
1385         }
1386             
1387
1388         case 0xfe: {
1389             struct modrm_byte * modrm = (struct modrm_byte *)&(instr[1]);
1390
1391             switch (modrm->reg) {
1392                 case 0:
1393                     return INC_8;
1394                 case 1:
1395                     return DEC_8;
1396                 default:
1397                     return INVALID_INSTR;
1398             }
1399         }
1400
1401         case 0xff: {
1402             struct modrm_byte * modrm = (struct modrm_byte *)&(instr[1]);
1403
1404             switch (modrm->reg) {
1405                 case 0:
1406                     return INC;
1407                 case 1:
1408                     return DEC;
1409                 default:
1410                     return INVALID_INSTR;
1411             }
1412         }
1413
1414         default:
1415             return INVALID_INSTR;
1416     }
1417 }
1418
1419
1420
1421 static char * op_form_to_str(op_form_t form) {
1422
1423     switch (form) {
1424         case LMSW: return "LMSW";
1425         case SMSW: return "SMSW";
1426         case CLTS: return "CLTS";
1427         case INVLPG: return "INVLPG";
1428         case MOV_CR2: return "MOV_CR2";
1429         case MOV_2CR: return "MOV_2CR";
1430         case MOV_DR2: return "MOV_DR2";
1431         case MOV_2DR: return "MOV_2DR";
1432         case MOV_SR2: return "MOV_SR2";
1433         case MOV_2SR: return "MOV_2SR";
1434         case MOV_MEM2_8: return "MOV_MEM2_8";
1435         case MOV_MEM2: return "MOV_MEM2";
1436         case MOV_2MEM_8: return "MOV_2MEM_8";
1437         case MOV_2MEM: return "MOV_2MEM";
1438         case MOV_MEM2AL_8: return "MOV_MEM2AL_8";
1439         case MOV_MEM2AX: return "MOV_MEM2AX";
1440         case MOV_AL2MEM_8: return "MOV_AL2MEM_8";
1441         case MOV_AX2MEM: return "MOV_AX2MEM";
1442         case MOV_IMM2_8: return "MOV_IMM2_8";
1443         case MOV_IMM2: return "MOV_IMM2";
1444         case MOVS_8: return "MOVS_8";
1445         case MOVS: return "MOVS";
1446         case MOVSX_8: return "MOVSX_8";
1447         case MOVSX: return "MOVSX";
1448         case MOVZX_8: return "MOVZX_8";
1449         case MOVZX: return "MOVZX";
1450         case HLT: return "HLT";
1451         case PUSHF: return "PUSHF";
1452         case POPF: return "POPF";
1453         case ADC_2MEM_8: return "ADC_2MEM_8";
1454         case ADC_2MEM: return "ADC_2MEM";
1455         case ADC_MEM2_8: return "ADC_MEM2_8";
1456         case ADC_MEM2: return "ADC_MEM2";
1457         case ADC_IMM2_8: return "ADC_IMM2_8";
1458         case ADC_IMM2: return "ADC_IMM2";
1459         case ADC_IMM2SX_8: return "ADC_IMM2SX_8";
1460         case ADD_IMM2_8: return "ADD_IMM2_8";
1461         case ADD_IMM2: return "ADD_IMM2";
1462         case ADD_IMM2SX_8: return "ADD_IMM2SX_8";
1463         case ADD_2MEM_8: return "ADD_2MEM_8";
1464         case ADD_2MEM: return "ADD_2MEM";
1465         case ADD_MEM2_8: return "ADD_MEM2_8";
1466         case ADD_MEM2: return "ADD_MEM2";
1467         case AND_MEM2_8: return "AND_MEM2_8";
1468         case AND_MEM2: return "AND_MEM2";
1469         case AND_2MEM_8: return "AND_2MEM_8";
1470         case AND_2MEM: return "AND_2MEM";
1471         case AND_IMM2_8: return "AND_IMM2_8";
1472         case AND_IMM2: return "AND_IMM2";
1473         case AND_IMM2SX_8: return "AND_IMM2SX_8";
1474         case OR_2MEM_8: return "OR_2MEM_8";
1475         case OR_2MEM: return "OR_2MEM";
1476         case OR_MEM2_8: return "OR_MEM2_8";
1477         case OR_MEM2: return "OR_MEM2";
1478         case OR_IMM2_8: return "OR_IMM2_8";
1479         case OR_IMM2: return "OR_IMM2";
1480         case OR_IMM2SX_8: return "OR_IMM2SX_8";
1481         case SUB_2MEM_8: return "SUB_2MEM_8";
1482         case SUB_2MEM: return "SUB_2MEM";
1483         case SUB_MEM2_8: return "SUB_MEM2_8";
1484         case SUB_MEM2: return "SUB_MEM2";
1485         case SUB_IMM2_8: return "SUB_IMM2_8";
1486         case SUB_IMM2: return "SUB_IMM2";
1487         case SUB_IMM2SX_8: return "SUB_IMM2SX_8";
1488         case XOR_2MEM_8: return "XOR_2MEM_8";
1489         case XOR_2MEM: return "XOR_2MEM";
1490         case XOR_MEM2_8: return "XOR_MEM2_8";
1491         case XOR_MEM2: return "XOR_MEM2";
1492         case XOR_IMM2_8: return "XOR_IMM2_8";
1493         case XOR_IMM2: return "XOR_IMM2";
1494         case XOR_IMM2SX_8: return "XOR_IMM2SX_8";
1495         case INC_8: return "INC_8";
1496         case INC: return "INC";
1497         case DEC_8: return "DEC_8";
1498         case DEC: return "DEC";
1499         case NEG_8: return "NEG_8";
1500         case NEG: return "NEG"; 
1501         case NOT_8: return "NOT_8";
1502         case NOT: return "NOT";
1503         case XCHG_8: return "XCHG_8";
1504         case XCHG: return "XCHG";
1505         case SETB: return "SETB";
1506         case SETBE: return "SETBE";
1507         case SETL: return "SETL";
1508         case SETLE: return "SETLE";
1509         case SETNB: return "SETNB";
1510         case SETNBE: return "SETNBE";
1511         case SETNL: return "SETNL";
1512         case SETNLE: return "SETNLE";
1513         case SETNO: return "SETNO";
1514         case SETNP: return "SETNP";
1515         case SETNS: return "SETNS";
1516         case SETNZ: return "SETNZ";
1517         case SETP: return "SETP";
1518         case SETS: return "SETS";
1519         case SETZ: return "SETZ";
1520         case SETO: return "SETO";
1521         case STOS_8: return "STOS_8";
1522         case STOS: return "STOS";
1523         case INT: return "INT";
1524
1525         case INVALID_INSTR:
1526         default:
1527             return "INVALID_INSTR";
1528     }
1529 }