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.
6 * The V3VEE Project is a joint project between Northwestern University
7 * and the University of New Mexico. You can find out more at
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.
14 * Author: Jack Lange <jarusl@cs.northwestern.edu>
16 * This is free software. You are permitted to use,
17 * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
20 #include <palacios/vmm_types.h>
23 /* .... Giant fucking switch tables */
138 static int get_addr_width(struct guest_info * info, struct x86_instr * instr,
141 switch (v3_get_vm_cpu_mode(info)) {
143 return (instr->prefixes.addr_size) ? 4 : 2;
146 return (instr->prefixes.addr_size) ? 2 : 4;
150 PrintError("Unsupported CPU mode: %d\n", info->cpu_mode);
155 static int get_operand_width(struct guest_info * info, struct x86_instr * instr,
255 switch (v3_get_vm_cpu_mode(info)) {
257 return (instr->prefixes.op_size) ? 4 : 2;
260 return (instr->prefixes.op_size) ? 2 : 4;
264 PrintError("Unsupported CPU mode: %d\n", info->cpu_mode);
269 switch (v3_get_vm_cpu_mode(info)) {
271 PrintError("Invalid instruction given operating mode (%d)\n", form);
279 PrintError("Unsupported CPU mode: %d\n", info->cpu_mode);
285 switch (v3_get_vm_cpu_mode(info)) {
294 PrintError("Unsupported CPU mode: %d\n", info->cpu_mode);
302 switch (v3_get_vm_cpu_mode(info)) {
310 PrintError("Unsupported CPU mode: %d\n", info->cpu_mode);
317 PrintError("Unsupported instruction form %d\n", form);
326 typedef enum {INVALID_ADDR_TYPE, REG, DISP0, DISP8, DISP16, DISP32} modrm_mode_t;
327 typedef enum {INVALID_REG_SIZE, REG64, REG32, REG16, REG8} reg_size_t;
334 } __attribute__((packed));
341 } __attribute__((packed));
348 static inline int decode_gpr(struct guest_info * core,
350 struct x86_operand * reg) {
352 struct v3_gprs * gprs = &(core->vm_regs);
356 reg->operand = (addr_t)&(gprs->rax);
359 reg->operand = (addr_t)&(gprs->rcx);
362 reg->operand = (addr_t)&(gprs->rdx);
365 reg->operand = (addr_t)&(gprs->rbx);
368 if (reg->size == 1) {
369 reg->operand = (addr_t)&(gprs->rax) + 1;
371 reg->operand = (addr_t)&(gprs->rsp);
375 if (reg->size == 1) {
376 reg->operand = (addr_t)&(gprs->rcx) + 1;
378 reg->operand = (addr_t)&(gprs->rbp);
382 if (reg->size == 1) {
383 reg->operand = (addr_t)&(gprs->rdx) + 1;
385 reg->operand = (addr_t)&(gprs->rsi);
389 if (reg->size == 1) {
390 reg->operand = (addr_t)&(gprs->rbx) + 1;
392 reg->operand = (addr_t)&(gprs->rdi);
396 PrintError("Invalid Reg Code (%d)\n", reg_code);
407 static inline int decode_cr(struct guest_info * core,
409 struct x86_operand * reg) {
411 struct v3_ctrl_regs * crs = &(core->ctrl_regs);
413 PrintDebug("\t Ctrl regs %d\n", reg_code);
417 reg->operand = (addr_t)&(crs->cr0);
420 reg->operand = (addr_t)&(crs->cr2);
423 reg->operand = (addr_t)&(crs->cr3);
426 reg->operand = (addr_t)&(crs->cr4);
430 PrintError("Invalid Reg Code (%d)\n", reg_code);
437 // This converts the displacement into the appropriate masked value
439 QUESTION: Are the register Values signed ?????
441 #define MASK_DISPLACEMENT(reg, mode) ({ \
443 if (mode == DISP8) { \
444 val = (sint8_t)(reg & 0xff); \
445 } else if (mode == DISP16) { \
446 val = (sint16_t)(reg & 0xffff); \
447 } else if (mode == DISP32) { \
448 val = (sint32_t)(reg & 0xffffffff); \
450 PrintError("Error invalid displacement size (%d)\n", mode); \
456 static int decode_rm_operand16(struct guest_info * core,
457 uint8_t * modrm_instr,
458 struct x86_instr * instr,
459 struct x86_operand * operand,
460 uint8_t * reg_code) {
462 struct v3_gprs * gprs = &(core->vm_regs);
463 struct modrm_byte * modrm = (struct modrm_byte *)modrm_instr;
464 addr_t base_addr = 0;
465 modrm_mode_t mod_mode = 0;
466 uint8_t * instr_cursor = modrm_instr;
468 // PrintDebug("ModRM mod=%d\n", modrm->mod);
470 *reg_code = modrm->reg;
474 if (modrm->mod == 3) {
475 //PrintDebug("first operand = Register (RM=%d)\n",modrm->rm);
476 operand->type = REG_OPERAND;
478 decode_gpr(core, modrm->rm, operand);
481 struct v3_segment * seg = NULL;
483 operand->type = MEM_OPERAND;
485 if (modrm->mod == 0) {
487 } else if (modrm->mod == 1) {
489 } else if (modrm->mod == 2) {
495 base_addr = gprs->rbx + MASK_DISPLACEMENT(gprs->rsi, mod_mode);
498 base_addr = gprs->rbx + MASK_DISPLACEMENT(gprs->rdi, mod_mode);
501 base_addr = gprs->rbp + MASK_DISPLACEMENT(gprs->rsi, mod_mode);
504 base_addr = gprs->rbp + MASK_DISPLACEMENT(gprs->rdi, mod_mode);
507 base_addr = gprs->rsi;
510 base_addr = gprs->rdi;
513 if (modrm->mod == 0) {
517 base_addr = gprs->rbp;
521 base_addr = gprs->rbx;
527 if (mod_mode == DISP8) {
528 base_addr += *(sint8_t *)instr_cursor;
530 } else if (mod_mode == DISP16) {
531 base_addr += *(sint16_t *)instr_cursor;
536 // get appropriate segment
537 if (instr->prefixes.cs_override) {
538 seg = &(core->segments.cs);
539 } else if (instr->prefixes.es_override) {
540 seg = &(core->segments.es);
541 } else if (instr->prefixes.ss_override) {
542 seg = &(core->segments.ss);
543 } else if (instr->prefixes.fs_override) {
544 seg = &(core->segments.fs);
545 } else if (instr->prefixes.gs_override) {
546 seg = &(core->segments.gs);
548 seg = &(core->segments.ds);
551 operand->operand = get_addr_linear(core, base_addr, seg);
555 return (instr_cursor - modrm_instr);
559 // returns num_bytes parsed
560 static int decode_rm_operand32(struct guest_info * core,
561 uint8_t * modrm_instr,
562 struct x86_instr * instr,
563 struct x86_operand * operand,
564 uint8_t * reg_code) {
566 struct v3_gprs * gprs = &(core->vm_regs);
567 uint8_t * instr_cursor = modrm_instr;
568 struct modrm_byte * modrm = (struct modrm_byte *)modrm_instr;
569 addr_t base_addr = 0;
570 modrm_mode_t mod_mode = 0;
571 uint_t has_sib_byte = 0;
574 *reg_code = modrm->reg;
578 if (modrm->mod == 3) {
579 operand->type = REG_OPERAND;
580 // PrintDebug("first operand = Register (RM=%d)\n",modrm->rm);
582 decode_gpr(core, modrm->rm, operand);
585 struct v3_segment * seg = NULL;
587 operand->type = MEM_OPERAND;
589 if (modrm->mod == 0) {
591 } else if (modrm->mod == 1) {
593 } else if (modrm->mod == 2) {
599 base_addr = gprs->rax;
602 base_addr = gprs->rcx;
605 base_addr = gprs->rdx;
608 base_addr = gprs->rbx;
614 if (modrm->mod == 0) {
618 base_addr = gprs->rbp;
622 base_addr = gprs->rsi;
625 base_addr = gprs->rdi;
631 struct sib_byte * sib = (struct sib_byte *)(instr_cursor);
632 int scale = 0x1 << sib->scale;
636 switch (sib->index) {
638 base_addr = gprs->rax;
641 base_addr = gprs->rcx;
644 base_addr = gprs->rdx;
647 base_addr = gprs->rbx;
653 base_addr = gprs->rbp;
656 base_addr = gprs->rsi;
659 base_addr = gprs->rdi;
668 base_addr += MASK_DISPLACEMENT(gprs->rax, mod_mode);
671 base_addr += MASK_DISPLACEMENT(gprs->rcx, mod_mode);
674 base_addr += MASK_DISPLACEMENT(gprs->rdx, mod_mode);
677 base_addr += MASK_DISPLACEMENT(gprs->rbx, mod_mode);
680 base_addr += MASK_DISPLACEMENT(gprs->rsp, mod_mode);
683 if (modrm->mod != 0) {
684 base_addr += MASK_DISPLACEMENT(gprs->rbp, mod_mode);
688 base_addr += MASK_DISPLACEMENT(gprs->rsi, mod_mode);
691 base_addr += MASK_DISPLACEMENT(gprs->rdi, mod_mode);
698 if (mod_mode == DISP8) {
699 base_addr += *(sint8_t *)instr_cursor;
701 } else if (mod_mode == DISP32) {
702 base_addr += *(sint32_t *)instr_cursor;
706 // get appropriate segment
707 if (instr->prefixes.cs_override) {
708 seg = &(core->segments.cs);
709 } else if (instr->prefixes.es_override) {
710 seg = &(core->segments.es);
711 } else if (instr->prefixes.ss_override) {
712 seg = &(core->segments.ss);
713 } else if (instr->prefixes.fs_override) {
714 seg = &(core->segments.fs);
715 } else if (instr->prefixes.gs_override) {
716 seg = &(core->segments.gs);
718 seg = &(core->segments.ds);
721 operand->operand = get_addr_linear(core, base_addr, seg);
725 return (instr_cursor - modrm_instr);
732 static int decode_rm_operand(struct guest_info * core,
733 uint8_t * instr_ptr, // input
734 struct x86_instr * instr,
735 struct x86_operand * operand,
736 uint8_t * reg_code) {
738 v3_cpu_mode_t mode = v3_get_vm_cpu_mode(core);
741 return decode_rm_operand16(core, instr_ptr, instr, operand, reg_code);
742 } else if ((mode == PROTECTED) || (mode == PROTECTED_PAE)) {
743 return decode_rm_operand32(core, instr_ptr, instr, operand, reg_code);
745 PrintError("Invalid CPU_MODE (%d)\n", mode);
752 static inline op_form_t op_code_to_form_0f(uint8_t * instr, int * length) {
757 struct modrm_byte * modrm = (struct modrm_byte *)&(instr[2]);
759 switch (modrm->reg) {
767 return INVALID_INSTR;
828 return INVALID_INSTR;
833 static op_form_t op_code_to_form(uint8_t * instr, int * length) {
857 return op_code_to_form_0f(instr, length);
897 struct modrm_byte * modrm = (struct modrm_byte *)&(instr[1]);
899 switch (modrm->reg) {
913 return INVALID_INSTR;
917 struct modrm_byte * modrm = (struct modrm_byte *)&(instr[1]);
919 switch (modrm->reg) {
933 return INVALID_INSTR;
937 struct modrm_byte * modrm = (struct modrm_byte *)&(instr[1]);
939 switch (modrm->reg) {
953 return INVALID_INSTR;
1010 struct modrm_byte * modrm = (struct modrm_byte *)&(instr[1]);
1012 switch (modrm->reg) {
1018 return INVALID_INSTR;
1022 struct modrm_byte * modrm = (struct modrm_byte *)&(instr[1]);
1024 switch (modrm->reg) {
1030 return INVALID_INSTR;
1036 struct modrm_byte * modrm = (struct modrm_byte *)&(instr[1]);
1038 switch (modrm->reg) {
1044 return INVALID_INSTR;
1049 struct modrm_byte * modrm = (struct modrm_byte *)&(instr[1]);
1051 switch (modrm->reg) {
1057 return INVALID_INSTR;
1062 return INVALID_INSTR;
1068 static char * op_form_to_str(op_form_t form) {
1071 case LMSW: return "LMSW";
1072 case SMSW: return "SMSW";
1073 case CLTS: return "CLTS";
1074 case INVLPG: return "INVLPG";
1075 case MOV_CR2: return "MOV_CR2";
1076 case MOV_2CR: return "MOV_2CR";
1077 case MOV_DR2: return "MOV_DR2";
1078 case MOV_2DR: return "MOV_2DR";
1079 case MOV_SR2: return "MOV_SR2";
1080 case MOV_2SR: return "MOV_2SR";
1081 case MOV_MEM2_8: return "MOV_MEM2_8";
1082 case MOV_MEM2: return "MOV_MEM2";
1083 case MOV_2MEM_8: return "MOV_2MEM_8";
1084 case MOV_2MEM: return "MOV_2MEM";
1085 case MOV_MEM2AL_8: return "MOV_MEM2AL_8";
1086 case MOV_MEM2AX: return "MOV_MEM2AX";
1087 case MOV_AL2MEM_8: return "MOV_AL2MEM_8";
1088 case MOV_AX2MEM: return "MOV_AX2MEM";
1089 case MOV_IMM2_8: return "MOV_IMM2_8";
1090 case MOV_IMM2: return "MOV_IMM2";
1091 case MOVS_8: return "MOVS_8";
1092 case MOVS: return "MOVS";
1093 case MOVSX_8: return "MOVSX_8";
1094 case MOVSX: return "MOVSX";
1095 case MOVZX_8: return "MOVZX_8";
1096 case MOVZX: return "MOVZX";
1097 case HLT: return "HLT";
1098 case PUSHF: return "PUSHF";
1099 case POPF: return "POPF";
1100 case ADC_2MEM_8: return "ADC_2MEM_8";
1101 case ADC_2MEM: return "ADC_2MEM";
1102 case ADC_MEM2_8: return "ADC_MEM2_8";
1103 case ADC_MEM2: return "ADC_MEM2";
1104 case ADC_IMM2_8: return "ADC_IMM2_8";
1105 case ADC_IMM2: return "ADC_IMM2";
1106 case ADC_IMM2SX_8: return "ADC_IMM2SX_8";
1107 case ADD_IMM2_8: return "ADD_IMM2_8";
1108 case ADD_IMM2: return "ADD_IMM2";
1109 case ADD_IMM2SX_8: return "ADD_IMM2SX_8";
1110 case ADD_2MEM_8: return "ADD_2MEM_8";
1111 case ADD_2MEM: return "ADD_2MEM";
1112 case ADD_MEM2_8: return "ADD_MEM2_8";
1113 case ADD_MEM2: return "ADD_MEM2";
1114 case AND_MEM2_8: return "AND_MEM2_8";
1115 case AND_MEM2: return "AND_MEM2";
1116 case AND_2MEM_8: return "AND_2MEM_8";
1117 case AND_2MEM: return "AND_2MEM";
1118 case AND_IMM2_8: return "AND_IMM2_8";
1119 case AND_IMM2: return "AND_IMM2";
1120 case AND_IMM2SX_8: return "AND_IMM2SX_8";
1121 case OR_2MEM_8: return "OR_2MEM_8";
1122 case OR_2MEM: return "OR_2MEM";
1123 case OR_MEM2_8: return "OR_MEM2_8";
1124 case OR_MEM2: return "OR_MEM2";
1125 case OR_IMM2_8: return "OR_IMM2_8";
1126 case OR_IMM2: return "OR_IMM2";
1127 case OR_IMM2SX_8: return "OR_IMM2SX_8";
1128 case SUB_2MEM_8: return "SUB_2MEM_8";
1129 case SUB_2MEM: return "SUB_2MEM";
1130 case SUB_MEM2_8: return "SUB_MEM2_8";
1131 case SUB_MEM2: return "SUB_MEM2";
1132 case SUB_IMM2_8: return "SUB_IMM2_8";
1133 case SUB_IMM2: return "SUB_IMM2";
1134 case SUB_IMM2SX_8: return "SUB_IMM2SX_8";
1135 case XOR_2MEM_8: return "XOR_2MEM_8";
1136 case XOR_2MEM: return "XOR_2MEM";
1137 case XOR_MEM2_8: return "XOR_MEM2_8";
1138 case XOR_MEM2: return "XOR_MEM2";
1139 case XOR_IMM2_8: return "XOR_IMM2_8";
1140 case XOR_IMM2: return "XOR_IMM2";
1141 case XOR_IMM2SX_8: return "XOR_IMM2SX_8";
1142 case INC_8: return "INC_8";
1143 case INC: return "INC";
1144 case DEC_8: return "DEC_8";
1145 case DEC: return "DEC";
1146 case NEG_8: return "NEG_8";
1147 case NEG: return "NEG";
1148 case NOT_8: return "NOT_8";
1149 case NOT: return "NOT";
1150 case XCHG_8: return "XCHG_8";
1151 case XCHG: return "XCHG";
1152 case SETB: return "SETB";
1153 case SETBE: return "SETBE";
1154 case SETL: return "SETL";
1155 case SETLE: return "SETLE";
1156 case SETNB: return "SETNB";
1157 case SETNBE: return "SETNBE";
1158 case SETNL: return "SETNL";
1159 case SETNLE: return "SETNLE";
1160 case SETNO: return "SETNO";
1161 case SETNP: return "SETNP";
1162 case SETNS: return "SETNS";
1163 case SETNZ: return "SETNZ";
1164 case SETP: return "SETP";
1165 case SETS: return "SETS";
1166 case SETZ: return "SETZ";
1167 case SETO: return "SETO";
1168 case STOS_8: return "STOS_8";
1169 case STOS: return "STOS";
1173 return "INVALID_INSTR";