* and the University of New Mexico. You can find out more at
* http://www.v3vee.org
*
- * Copyright (c) 2011, Jack Lange <jarusl@cs.northwestern.edu>
- * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
+ * Copyright (c) 2012, Alexander Kudryavtsev <alexk@ispras.ru>
+ * Copyright (c) 2012, The V3VEE Project <http://www.v3vee.org>
* All rights reserved.
*
* Author: Alexander Kudryavtsev <alexk@ispras.ru>
return 0;
}
-static int get_opcode(qx86_insn *inst);
+static int get_opcode(qx86_insn *inst, struct guest_info *core);
static int qx86_register_to_v3_reg(struct guest_info * info, int qx86_reg,
addr_t * v3_reg, uint_t * reg_len);
-static int decode_string_op(struct guest_info * info,
- const qx86_insn * qx86_inst, struct x86_instr * instr)
-{
- int status = 0;
- PrintDebug("String operation\n");
-
- if (instr->prefixes.rep == 1) {
- uint64_t a_mask = ~(~0ULL <<
- (QX86_SIZE_OCTETS(qx86_inst->attributes.addressSize) * 8));
-
- instr->str_op_length = info->vm_regs.rcx & a_mask;
- } else {
- instr->str_op_length = 1;
- }
-
-
- if (instr->op_type == V3_OP_MOVS) {
- instr->num_operands = 2;
-
- if((status = qx86_calculate_linear_address(qx86_inst, 0,
- (qx86_uint64*)&instr->dst_operand.operand)) != QX86_SUCCESS) {
- PrintError("Could not get destination memory operand: "
- "qx86_calculate_linear_address: %d\n", status);
- return -1;
- }
-
- if((status = qx86_calculate_linear_address(qx86_inst, 1,
- (qx86_uint64*)&instr->src_operand.operand)) != QX86_SUCCESS) {
- PrintError("Could not get source memory operand: "
- "qx86_calculate_linear_address: %d\n", status);
- return -1;
- }
-
- instr->dst_operand.write = 1;
- instr->src_operand.read = 1;
-
- } else if (instr->op_type == V3_OP_STOS) {
- instr->num_operands = 2;
-
- if((status = qx86_calculate_linear_address(qx86_inst, 0,
- (qx86_uint64*)&instr->dst_operand.operand)) != QX86_SUCCESS) {
- PrintError("Could not get destination memory operand: "
- "qx86_calculate_linear_address: %d\n", status);
- return -1;
- }
-
- // STOS reads from rax
- qx86_register_to_v3_reg(info,
- qx86_inst->operands[1].u.r.rindex,
- &(instr->src_operand.operand), &(instr->src_operand.size));
- instr->src_operand.type = REG_OPERAND;
-
- instr->src_operand.read = 1;
- instr->dst_operand.write = 1;
-
- } else {
- PrintError("Unhandled String OP\n");
- return -1;
- }
-
- return 0;
-}
-
static int callback(void *data, int rindex, int subreg, unsigned char *value) {
void* reg_addr = 0;
uint_t reg_size;
(addr_t*)®_addr, ®_size);
if(v3_reg_type == -1) {
- PrintError("Callback failed to get register index %d\n", rindex);
+ PrintError(info->vm_info, info, "Callback failed to get register index %d\n", rindex);
return 0;
}
*(uint32_t*)value = ((struct v3_segment*)reg_addr)->limit;
break;
case QX86_SUBREG_FLAGS:
- PrintError("Callback doesn't know how to give flags.\n");
+ PrintError(info->vm_info, info, "Callback doesn't know how to give flags.\n");
return 0;
case QX86_SUBREG_NONE: {
- switch(qx86_rtab[rindex].size) {
+ switch(qx86_rinfo(rindex)->size) {
case 1: *(uint8_t* )value = *(uint8_t* )reg_addr; break;
case 2: *(uint16_t*)value = *(uint16_t*)reg_addr; break;
case 4: *(uint32_t*)value = *(uint32_t*)reg_addr; break;
&(v3_op->operand), &(v3_op->size));
if (v3_reg_type == -1) {
- PrintError("Operand %d is an Unhandled Operand: %s\n", op_num,
- qx86_rtab[qx86_op->u.r.rindex].name);
+ PrintError(info->vm_info, info, "Operand %d is an Unhandled Operand: %s\n", op_num,
+ qx86_rinfo(qx86_op->u.r.rindex)->name);
v3_op->type = INVALID_OPERAND;
return -1;
} else if (v3_reg_type == SEGMENT_REGISTER) {
v3_op->type = REG_OPERAND;
} else if(qx86_op->ot == QX86_OPERAND_TYPE_MEMORY) {
- PrintDebug("Memory operand (%d)\n", op_num);
+ PrintDebug(info->vm_info, info, "Memory operand (%d)\n", op_num);
if((status = qx86_calculate_linear_address(qx86_insn, op_num,
(qx86_uint64*)&v3_op->operand)) != QX86_SUCCESS) {
- PrintError("Could not get memory operand %d: "
+ PrintError(info->vm_info, info, "Could not get memory operand %d: "
"qx86_calculate_linear_address() returns %d\n", op_num, status);
return -1;
}
v3_op->size = qx86_op->u.i.valueSize;
if (v3_op->size > 4) {
- PrintError("Unhandled 64 bit immediates\n");
+ PrintError(info->vm_info, info, "Unhandled 64 bit immediates\n");
return -1;
}
v3_op->operand = (addr_t)*(uint64_t*)qx86_op->u.i.value;
v3_op->type = IMM_OPERAND;
} else {
- PrintError("Unhandled Operand %d Type %d\n", op_num, qx86_op->ot);
+ PrintError(info->vm_info, info, "Unhandled Operand %d Type %d\n", op_num, qx86_op->ot);
return -1;
}
case LONG:
proc_mode = QX86_SIZE_64; break;
default:
- PrintError("Unsupported CPU mode: %d\n", info->cpu_mode);
+ PrintError(info->vm_info, info, "Unsupported CPU mode: %d\n", info->cpu_mode);
return -1;
}
(info->rip & ~0xfffULL) + 0x1000, &(info->segments.cs)), &instr_ptr2);
}
if (status == -1) {
- PrintError("Could not translate Instruction Address at second stage "
+ PrintError(info->vm_info, info, "Could not translate Instruction Address at second stage "
"translation (%p)\n", (void *)(addr_t)info->rip);
return -1;
}
if(((instr_ptr & ~0xfffUL) + 0x1000) != instr_ptr2) {
- PrintError("Note: physical page non-contiguous\n");
+ PrintError(info->vm_info, info, "Note: physical page non-contiguous\n");
memcpy(inst_buf, (const void*)instr_ptr, left_in_page);
memcpy(inst_buf + left_in_page, (const void*)instr_ptr2,
QX86_INSN_SIZE_MAX - left_in_page);
int status = qx86_decode(&qx86_inst, proc_mode,
(const void*)instr_ptr, QX86_INSN_SIZE_MAX);
if(status != QX86_SUCCESS) {
- PrintError("qx86_decode() returned %d\n", status);
+ PrintError(info->vm_info, info, "qx86_decode() returned %d\n", status);
return -1;
}
instr->instr_length = qx86_inst.rawSize;
- if ((instr->op_type = get_opcode(&qx86_inst)) == V3_INVALID_OP) {
- PrintError("Could not get opcode. (mnemonic=%s)\n",
- qx86_mtab[qx86_inst.mnemonic].name);
+ if ((instr->op_type = get_opcode(&qx86_inst, info)) == V3_INVALID_OP) {
+ PrintError(info->vm_info, info, "Could not get opcode. (mnemonic=%s)\n",
+ qx86_minfo(qx86_inst.mnemonic)->name);
return -1;
}
if(instr->op_type == V3_OP_MOVS || instr->op_type == V3_OP_STOS) {
instr->is_str_op = 1;
- return decode_string_op(info, &qx86_inst, instr);
+ if (instr->prefixes.rep == 1) {
+ uint64_t a_mask = (~0ULL >>
+ (64 - QX86_SIZE_OCTETS(qx86_inst.attributes.addressSize) * 8));
+
+ instr->str_op_length = info->vm_regs.rcx & a_mask;
+ } else {
+ instr->str_op_length = 1;
+ }
} else {
instr->is_str_op = 0;
instr->str_op_length = 0;
char buf[128];
int buf_sz = 128;
if(qx86_print_intel(&qx86_inst, &opt, buf, &buf_sz) != QX86_SUCCESS) {
- PrintDebug("Print failed!\n");
+ PrintDebug(info->vm_info, info, "Print failed!\n");
} else {
- PrintDebug("Instruction (%p): %s\n", (void*)info->rip, buf);
+ PrintDebug(info->vm_info, info, "Instruction (%p): %s\n", (void*)info->rip, buf);
}
- PrintDebug("Operands: dst %p src %p 3rd %p\n", (void*)instr->dst_operand.operand,
+ PrintDebug(info->vm_info, info, "Operands: dst %p src %p 3rd %p\n", (void*)instr->dst_operand.operand,
(void*)instr->src_operand.operand, (void*)instr->third_operand.operand);
#endif
return 0;
}
-static int get_opcode(qx86_insn *inst) {
+static int get_opcode(qx86_insn *inst, struct guest_info *core) {
switch (inst->mnemonic) {
#define IS_CR(op) inst->operands[op].ot == QX86_OPERAND_TYPE_REGISTER && \
- qx86_rtab[inst->operands[op].u.r.rindex].rclass == QX86_RCLASS_CREG
+ qx86_rinfo(inst->operands[op].u.r.rindex)->rclass == QX86_RCLASS_CREG
/* MOV cases */
case QX86_MNEMONIC_MOV: {
if(IS_CR(1))
return V3_OP_MOVCR2;
- PrintError("Bad operand types for MOV: %d %d\n", inst->operands[0].ot,
+ PrintError(core->vm_info, core, "Bad operand types for MOV: %d %d\n", inst->operands[0].ot,
inst->operands[1].ot);
return V3_INVALID_OP;
}
static int qx86_register_to_v3_reg(struct guest_info * info, int qx86_reg,
addr_t * v3_reg, uint_t * reg_len) {
- PrintDebug("qx86 Register: %s\n", qx86_rtab[qx86_reg].name);
+ PrintDebug(info->vm_info, info, "qx86 Register: %s\n", qx86_rinfo(qx86_reg)->name);
switch (qx86_reg) {
case QX86_REGISTER_INVALID:
*reg_len = 4;
return CTRL_REGISTER;
case QX86_REGISTER_CR8:
- *v3_reg = (addr_t)&(info->ctrl_regs.cr8);
+ *v3_reg = (addr_t)&(info->ctrl_regs.apic_tpr);
*reg_len = 4;
return CTRL_REGISTER;