#include <palacios/vmm_lowlevel.h>
#include <palacios/vmm_sprintf.h>
#include <palacios/vmm_muxer.h>
+#include <palacios/vmm_xed.h>
v3_cpu_mode_t v3_get_vm_cpu_mode(struct guest_info * info) {
}
+static int safe_gva_to_hva(struct guest_info * info, addr_t linear_addr, addr_t * host_addr) {
+ /* select the proper translation based on guest mode */
+ if (info->mem_mode == PHYSICAL_MEM) {
+ if (v3_gpa_to_hva(info, linear_addr, host_addr) == -1) return -1;
+ } else if (info->mem_mode == VIRTUAL_MEM) {
+ if (v3_gva_to_hva(info, linear_addr, host_addr) == -1) return -1;
+ }
+ return 0;
+}
+
+static int v3_print_disassembly(struct guest_info * info) {
+ int passed_rip = 0;
+ addr_t rip, rip_linear, rip_host;
+
+ /* we don't know where the instructions preceding RIP start, so we just take
+ * a guess and hope the instruction stream synced up with our disassembly
+ * some time before RIP; if it has not we correct RIP at that point
+ */
+
+ /* start disassembly 64 bytes before current RIP, continue 32 bytes after */
+ rip = (addr_t) info->rip - 64;
+ while ((int) (rip - info->rip) < 32) {
+ /* always print RIP, even if the instructions before were bad */
+ if (!passed_rip && rip >= info->rip) {
+ if (rip != info->rip) {
+ V3_Print("***** bad disassembly up to this point *****\n");
+ rip = info->rip;
+ }
+ passed_rip = 1;
+ }
+
+ /* look up host virtual address for this instruction */
+ rip_linear = get_addr_linear(info, rip, &(info->segments.cs));
+ if (safe_gva_to_hva(info, rip_linear, &rip_host) < 0) {
+ rip++;
+ continue;
+ }
+
+ /* print disassembled instrcution (updates rip) */
+ if (v3_disasm(info, (void *) rip_host, &rip, rip == info->rip) < 0) {
+ rip++;
+ continue;
+ }
+ }
+
+ return 0;
+}
+
+
void v3_print_guest_state(struct guest_info * info) {
addr_t linear_addr = 0;
v3_print_mem_map(info->vm_info);
v3_print_stack(info);
+
+ v3_print_disassembly(info);
}
+int v3_disasm(struct guest_info * info, void *instr_ptr, addr_t * rip, int mark) {
+ char buffer[256];
+ int i;
+ unsigned length;
+ xed_decoded_inst_t xed_instr;
+ xed_error_enum_t xed_error;
+
+ /* disassemble the specified instruction */
+ if (set_decoder_mode(info, info->decoder_state) == -1) {
+ PrintError("Could not set decoder mode\n");
+ return -1;
+ }
+
+ xed_decoded_inst_zero_set_mode(&xed_instr, info->decoder_state);
+
+ xed_error = xed_decode(&xed_instr,
+ REINTERPRET_CAST(const xed_uint8_t *, instr_ptr),
+ XED_MAX_INSTRUCTION_BYTES);
+
+ if (xed_error != XED_ERROR_NONE) {
+ PrintError("Xed error: %s\n", xed_error_enum_t2str(xed_error));
+ return -1;
+ }
+
+ /* obtain string representation in AT&T syntax */
+ if (!xed_format_att(&xed_instr, buffer, sizeof(buffer), *rip)) {
+ PrintError("Xed error: cannot disaaemble\n");
+ return -1;
+ }
+
+ /* print address, opcode bytes and the disassembled instruction */
+ length = xed_decoded_inst_get_length(&xed_instr);
+ V3_Print("0x%p %c ", (void *) *rip, mark ? '*' : ' ');
+ for (i = 0; i < length; i++) {
+ unsigned char b = ((unsigned char *) instr_ptr)[i];
+ V3_Print("%x%x ", b >> 4, b & 0xf);
+ }
+ while (i++ < 8) {
+ V3_Print(" ");
+ }
+ V3_Print("%s\n", buffer);
+
+ /* move on to next instruction */
+ *rip += length;
+ return 0;
+}
+
+
+
int v3_decode(struct guest_info * info, addr_t instr_ptr, struct x86_instr * instr) {
xed_decoded_inst_t xed_instr;
xed_error_enum_t xed_error;