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 v3_gprs * gprs,
350 struct x86_operand * reg) {
354 reg->operand = (addr_t)&(gprs->rax);
357 reg->operand = (addr_t)&(gprs->rcx);
360 reg->operand = (addr_t)&(gprs->rdx);
363 reg->operand = (addr_t)&(gprs->rbx);
366 if (reg->size == 1) {
367 reg->operand = (addr_t)&(gprs->rax) + 1;
369 reg->operand = (addr_t)&(gprs->rsp);
373 if (reg->size == 1) {
374 reg->operand = (addr_t)&(gprs->rcx) + 1;
376 reg->operand = (addr_t)&(gprs->rbp);
380 if (reg->size == 1) {
381 reg->operand = (addr_t)&(gprs->rdx) + 1;
383 reg->operand = (addr_t)&(gprs->rsi);
387 if (reg->size == 1) {
388 reg->operand = (addr_t)&(gprs->rbx) + 1;
390 reg->operand = (addr_t)&(gprs->rdi);
402 // This converts the displacement into the appropriate masked value
404 QUESTION: Are the register Values signed ?????
406 #define MASK_DISPLACEMENT(reg, mode) ({ \
408 if (mode == DISP8) { \
409 val = (sint8_t)(reg & 0xff); \
410 } else if (mode == DISP16) { \
411 val = (sint16_t)(reg & 0xffff); \
412 } else if (mode == DISP32) { \
413 val = (sint32_t)(reg & 0xffffffff); \
415 PrintError("Error invalid displacement size (%d)\n", mode); \
421 static int decode_rm_operand16(struct guest_info * core,
422 uint8_t * modrm_instr,
423 struct x86_instr * instr,
424 struct x86_operand * operand,
425 uint8_t * reg_code) {
427 struct v3_gprs * gprs = &(core->vm_regs);
428 struct modrm_byte * modrm = (struct modrm_byte *)modrm_instr;
429 addr_t base_addr = 0;
430 modrm_mode_t mod_mode = 0;
431 uint8_t * instr_cursor = modrm_instr;
433 // PrintDebug("ModRM mod=%d\n", modrm->mod);
435 *reg_code = modrm->reg;
439 if (modrm->mod == 3) {
440 //PrintDebug("first operand = Register (RM=%d)\n",modrm->rm);
441 operand->type = REG_OPERAND;
443 decode_gpr(gprs, modrm->rm, operand);
446 struct v3_segment * seg = NULL;
448 operand->type = MEM_OPERAND;
450 if (modrm->mod == 0) {
452 } else if (modrm->mod == 1) {
454 } else if (modrm->mod == 2) {
460 base_addr = gprs->rbx + MASK_DISPLACEMENT(gprs->rsi, mod_mode);
463 base_addr = gprs->rbx + MASK_DISPLACEMENT(gprs->rdi, mod_mode);
466 base_addr = gprs->rbp + MASK_DISPLACEMENT(gprs->rsi, mod_mode);
469 base_addr = gprs->rbp + MASK_DISPLACEMENT(gprs->rdi, mod_mode);
472 base_addr = gprs->rsi;
475 base_addr = gprs->rdi;
478 if (modrm->mod == 0) {
482 base_addr = gprs->rbp;
486 base_addr = gprs->rbx;
492 if (mod_mode == DISP8) {
493 base_addr += *(sint8_t *)instr_cursor;
495 } else if (mod_mode == DISP16) {
496 base_addr += *(sint16_t *)instr_cursor;
501 // get appropriate segment
502 if (instr->prefixes.cs_override) {
503 seg = &(core->segments.cs);
504 } else if (instr->prefixes.es_override) {
505 seg = &(core->segments.es);
506 } else if (instr->prefixes.ss_override) {
507 seg = &(core->segments.ss);
508 } else if (instr->prefixes.fs_override) {
509 seg = &(core->segments.fs);
510 } else if (instr->prefixes.gs_override) {
511 seg = &(core->segments.gs);
513 seg = &(core->segments.ds);
516 operand->operand = get_addr_linear(core, base_addr, seg);
520 return (instr_cursor - modrm_instr);
524 // returns num_bytes parsed
525 static int decode_rm_operand32(struct guest_info * core,
526 uint8_t * modrm_instr,
527 struct x86_instr * instr,
528 struct x86_operand * operand,
529 uint8_t * reg_code) {
531 struct v3_gprs * gprs = &(core->vm_regs);
532 uint8_t * instr_cursor = modrm_instr;
533 struct modrm_byte * modrm = (struct modrm_byte *)modrm_instr;
534 addr_t base_addr = 0;
535 modrm_mode_t mod_mode = 0;
536 uint_t has_sib_byte = 0;
539 *reg_code = modrm->reg;
543 if (modrm->mod == 3) {
544 operand->type = REG_OPERAND;
545 // PrintDebug("first operand = Register (RM=%d)\n",modrm->rm);
547 decode_gpr(gprs, modrm->rm, operand);
550 struct v3_segment * seg = NULL;
552 operand->type = MEM_OPERAND;
554 if (modrm->mod == 0) {
556 } else if (modrm->mod == 1) {
558 } else if (modrm->mod == 2) {
564 base_addr = gprs->rax;
567 base_addr = gprs->rcx;
570 base_addr = gprs->rdx;
573 base_addr = gprs->rbx;
579 if (modrm->mod == 0) {
583 base_addr = gprs->rbp;
587 base_addr = gprs->rsi;
590 base_addr = gprs->rdi;
596 struct sib_byte * sib = (struct sib_byte *)(instr_cursor);
597 int scale = 0x1 << sib->scale;
601 switch (sib->index) {
603 base_addr = gprs->rax;
606 base_addr = gprs->rcx;
609 base_addr = gprs->rdx;
612 base_addr = gprs->rbx;
618 base_addr = gprs->rbp;
621 base_addr = gprs->rsi;
624 base_addr = gprs->rdi;
633 base_addr += MASK_DISPLACEMENT(gprs->rax, mod_mode);
636 base_addr += MASK_DISPLACEMENT(gprs->rcx, mod_mode);
639 base_addr += MASK_DISPLACEMENT(gprs->rdx, mod_mode);
642 base_addr += MASK_DISPLACEMENT(gprs->rbx, mod_mode);
645 base_addr += MASK_DISPLACEMENT(gprs->rsp, mod_mode);
648 if (modrm->mod != 0) {
649 base_addr += MASK_DISPLACEMENT(gprs->rbp, mod_mode);
653 base_addr += MASK_DISPLACEMENT(gprs->rsi, mod_mode);
656 base_addr += MASK_DISPLACEMENT(gprs->rdi, mod_mode);
663 if (mod_mode == DISP8) {
664 base_addr += *(sint8_t *)instr_cursor;
666 } else if (mod_mode == DISP32) {
667 base_addr += *(sint32_t *)instr_cursor;
671 // get appropriate segment
672 if (instr->prefixes.cs_override) {
673 seg = &(core->segments.cs);
674 } else if (instr->prefixes.es_override) {
675 seg = &(core->segments.es);
676 } else if (instr->prefixes.ss_override) {
677 seg = &(core->segments.ss);
678 } else if (instr->prefixes.fs_override) {
679 seg = &(core->segments.fs);
680 } else if (instr->prefixes.gs_override) {
681 seg = &(core->segments.gs);
683 seg = &(core->segments.ds);
686 operand->operand = get_addr_linear(core, base_addr, seg);
690 return (instr_cursor - modrm_instr);
697 static int decode_rm_operand(struct guest_info * core,
698 uint8_t * instr_ptr, // input
699 struct x86_instr * instr,
700 struct x86_operand * operand,
701 uint8_t * reg_code) {
703 v3_cpu_mode_t mode = v3_get_vm_cpu_mode(core);
706 return decode_rm_operand16(core, instr_ptr, instr, operand, reg_code);
707 } else if ((mode == PROTECTED) || (mode == PROTECTED_PAE)) {
708 return decode_rm_operand32(core, instr_ptr, instr, operand, reg_code);
710 PrintError("Invalid CPU_MODE (%d)\n", mode);
717 static inline op_form_t op_code_to_form_0f(uint8_t * instr, int * length) {
722 struct modrm_byte * modrm = (struct modrm_byte *)&(instr[2]);
724 switch (modrm->reg) {
732 return INVALID_INSTR;
793 return INVALID_INSTR;
798 static op_form_t op_code_to_form(uint8_t * instr, int * length) {
822 return op_code_to_form_0f(instr, length);
862 struct modrm_byte * modrm = (struct modrm_byte *)&(instr[1]);
864 switch (modrm->reg) {
878 return INVALID_INSTR;
882 struct modrm_byte * modrm = (struct modrm_byte *)&(instr[1]);
884 switch (modrm->reg) {
898 return INVALID_INSTR;
902 struct modrm_byte * modrm = (struct modrm_byte *)&(instr[1]);
904 switch (modrm->reg) {
918 return INVALID_INSTR;
975 struct modrm_byte * modrm = (struct modrm_byte *)&(instr[1]);
977 switch (modrm->reg) {
983 return INVALID_INSTR;
987 struct modrm_byte * modrm = (struct modrm_byte *)&(instr[1]);
989 switch (modrm->reg) {
995 return INVALID_INSTR;
1001 struct modrm_byte * modrm = (struct modrm_byte *)&(instr[1]);
1003 switch (modrm->reg) {
1009 return INVALID_INSTR;
1014 struct modrm_byte * modrm = (struct modrm_byte *)&(instr[1]);
1016 switch (modrm->reg) {
1022 return INVALID_INSTR;
1027 return INVALID_INSTR;