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.h>
21 #include <palacios/vmm_emulator.h>
22 #include <palacios/vm_guest_mem.h>
23 #include <palacios/vmm_decoder.h>
24 #include <palacios/vmm_paging.h>
25 #include <palacios/vmm_instr_emulator.h>
27 #ifndef CONFIG_DEBUG_EMULATOR
29 #define PrintDebug(fmt, args...)
33 static int run_op(struct guest_info * info, v3_op_type_t op_type, addr_t src_addr, addr_t dst_addr, int src_op_size, int dst_op_size);
35 // We emulate up to the next 4KB page boundry
36 static int emulate_string_write_op(struct guest_info * info, struct x86_instr * dec_instr,
37 addr_t write_gva, addr_t write_gpa, addr_t dst_addr,
38 int (*write_fn)(struct guest_info * core, addr_t guest_addr, void * src, uint_t length, void * priv_data),
40 uint_t emulation_length = 0;
41 uint_t emulation_iter_cnt = 0;
45 if (dec_instr->dst_operand.operand != write_gva) {
46 PrintError("Inconsistency between Pagefault and Instruction Decode XED_ADDR=%p, PF_ADDR=%p\n",
47 (void *)dec_instr->dst_operand.operand, (void *)write_gva);
51 /*emulation_length = ( (dec_instr->str_op_length < (0x1000 - PAGE_OFFSET_4KB(write_gva))) ?
52 dec_instr->str_op_length :
53 (0x1000 - PAGE_OFFSET_4KB(write_gva)));*/
54 emulation_length = ( (dec_instr->str_op_length * (dec_instr->dst_operand.size) < (0x1000 - PAGE_OFFSET_4KB(write_gva))) ?
55 dec_instr->str_op_length * dec_instr->dst_operand.size :
56 (0x1000 - PAGE_OFFSET_4KB(write_gva)));
58 /* ** Fix emulation length so that it doesn't overrun over the src page either ** */
59 emulation_iter_cnt = emulation_length / dec_instr->dst_operand.size;
60 tmp_rcx = emulation_iter_cnt;
62 if (dec_instr->op_type == V3_OP_MOVS) {
64 // figure out addresses here....
65 if (info->mem_mode == PHYSICAL_MEM) {
66 if (v3_gpa_to_hva(info, dec_instr->src_operand.operand, &src_addr) == -1) {
67 PrintError("Could not translate write Source (Physical) to host VA\n");
71 if (v3_gva_to_hva(info, dec_instr->src_operand.operand, &src_addr) == -1) {
72 PrintError("Could not translate write Source (Virtual) to host VA\n");
77 if (dec_instr->dst_operand.size == 1) {
78 movs8((addr_t *)&dst_addr, &src_addr, &tmp_rcx, (addr_t *)&(info->ctrl_regs.rflags));
79 } else if (dec_instr->dst_operand.size == 2) {
80 movs16((addr_t *)&dst_addr, &src_addr, &tmp_rcx, (addr_t *)&(info->ctrl_regs.rflags));
81 } else if (dec_instr->dst_operand.size == 4) {
82 movs32((addr_t *)&dst_addr, &src_addr, &tmp_rcx, (addr_t *)&(info->ctrl_regs.rflags));
84 } else if (dec_instr->dst_operand.size == 8) {
85 movs64((addr_t *)&dst_addr, &src_addr, &tmp_rcx, (addr_t *)&(info->ctrl_regs.rflags));
88 PrintError("Invalid operand length\n");
92 info->vm_regs.rdi += emulation_length;
93 info->vm_regs.rsi += emulation_length;
95 // RCX is only modified if the rep prefix is present
96 if (dec_instr->prefixes.rep == 1) {
97 info->vm_regs.rcx -= emulation_iter_cnt;
100 } else if (dec_instr->op_type == V3_OP_STOS) {
102 if (dec_instr->dst_operand.size == 1) {
103 stos8((addr_t *)&dst_addr, (addr_t *)&(info->vm_regs.rax), &tmp_rcx, (addr_t *)&(info->ctrl_regs.rflags));
104 } else if (dec_instr->dst_operand.size == 2) {
105 stos16((addr_t *)&dst_addr, (addr_t *)&(info->vm_regs.rax), &tmp_rcx, (addr_t *)&(info->ctrl_regs.rflags));
106 } else if (dec_instr->dst_operand.size == 4) {
107 stos32((addr_t *)&dst_addr, (addr_t *)&(info->vm_regs.rax), &tmp_rcx, (addr_t *)&(info->ctrl_regs.rflags));
109 } else if (dec_instr->dst_operand.size == 8) {
110 stos64((addr_t *)&dst_addr, (addr_t *)&(info->vm_regs.rax), &tmp_rcx, (addr_t *)&(info->ctrl_regs.rflags));
113 PrintError("Invalid operand length\n");
117 info->vm_regs.rdi += emulation_length;
119 // RCX is only modified if the rep prefix is present
120 if (dec_instr->prefixes.rep == 1) {
121 info->vm_regs.rcx -= emulation_iter_cnt;
125 PrintError("Unimplemented String operation\n");
129 if (write_fn(info, write_gpa, (void *)dst_addr, emulation_length, priv_data) != emulation_length) {
130 PrintError("Did not fully read hooked data\n");
134 if (emulation_length == dec_instr->str_op_length) {
135 info->rip += dec_instr->instr_length;
138 return emulation_length;
142 static int emulate_xchg_write_op(struct guest_info * info, struct x86_instr * dec_instr,
143 addr_t write_gva, addr_t write_gpa, addr_t dst_addr,
144 int (*write_fn)(struct guest_info * core, addr_t guest_addr, void * src, uint_t length, void * priv_data),
147 addr_t em_dst_addr = 0;
150 PrintDebug("Emulating XCHG write\n");
152 if (dec_instr->src_operand.type == MEM_OPERAND) {
153 if (info->shdw_pg_mode == SHADOW_PAGING) {
154 if (dec_instr->src_operand.operand != write_gva) {
155 PrintError("XCHG: Inconsistency between Pagefault and Instruction Decode XED_ADDR=%p, PF_ADDR=%p\n",
156 (void *)dec_instr->src_operand.operand, (void *)write_gva);
162 } else if (dec_instr->src_operand.type == REG_OPERAND) {
163 src_addr = dec_instr->src_operand.operand;
165 src_addr = (addr_t)&(dec_instr->src_operand.operand);
170 if (dec_instr->dst_operand.type == MEM_OPERAND) {
171 if (info->shdw_pg_mode == SHADOW_PAGING) {
172 if (dec_instr->dst_operand.operand != write_gva) {
173 PrintError("XCHG: Inconsistency between Pagefault and Instruction Decode XED_ADDR=%p, PF_ADDR=%p\n",
174 (void *)dec_instr->dst_operand.operand, (void *)write_gva);
178 //check that the operand (GVA) maps to the the faulting GPA
181 em_dst_addr = dst_addr;
182 } else if (dec_instr->src_operand.type == REG_OPERAND) {
183 em_dst_addr = dec_instr->src_operand.operand;
185 em_dst_addr = (addr_t)&(dec_instr->src_operand.operand);
188 dst_op_len = dec_instr->dst_operand.size;
189 src_op_len = dec_instr->src_operand.size;
191 PrintDebug("Dst_Addr = %p, SRC operand = %p\n",
192 (void *)dst_addr, (void *)src_addr);
195 if (run_op(info, dec_instr->op_type, src_addr, em_dst_addr, src_op_len, dst_op_len) == -1) {
196 PrintError("Instruction Emulation Failed\n");
200 if (write_fn(info, write_gpa, (void *)dst_addr, dst_op_len, priv_data) != dst_op_len) {
201 PrintError("Did not fully write hooked data\n");
205 info->rip += dec_instr->instr_length;
212 static int emulate_xchg_read_op(struct guest_info * info, struct x86_instr * dec_instr,
213 addr_t read_gva, addr_t read_gpa, addr_t src_addr,
214 int (*read_fn)(struct guest_info * core, addr_t guest_addr, void * dst, uint_t length, void * priv_data),
215 int (*write_fn)(struct guest_info * core, addr_t guest_addr, void * src, uint_t length, void * priv_data),
217 addr_t em_src_addr = 0;
218 addr_t em_dst_addr = 0;
222 PrintDebug("Emulating XCHG Read\n");
224 if (dec_instr->src_operand.type == MEM_OPERAND) {
225 if (dec_instr->src_operand.operand != read_gva) {
226 PrintError("XCHG: Inconsistency between Pagefault and Instruction Decode XED_ADDR=%p, PF_ADDR=%p\n",
227 (void *)dec_instr->src_operand.operand, (void *)read_gva);
231 em_src_addr = src_addr;
232 } else if (dec_instr->src_operand.type == REG_OPERAND) {
233 em_src_addr = dec_instr->src_operand.operand;
235 em_src_addr = (addr_t)&(dec_instr->src_operand.operand);
240 if (dec_instr->dst_operand.type == MEM_OPERAND) {
241 if (info->shdw_pg_mode == SHADOW_PAGING) {
242 if (dec_instr->dst_operand.operand != read_gva) {
243 PrintError("XCHG: Inconsistency between Pagefault and Instruction Decode XED_ADDR=%p, PF_ADDR=%p\n",
244 (void *)dec_instr->dst_operand.operand, (void *)read_gva);
248 //check that the operand (GVA) maps to the the faulting GPA
251 em_dst_addr = src_addr;
252 } else if (dec_instr->src_operand.type == REG_OPERAND) {
253 em_dst_addr = dec_instr->src_operand.operand;
255 em_dst_addr = (addr_t)&(dec_instr->src_operand.operand);
258 dst_op_len = dec_instr->dst_operand.size;
259 src_op_len = dec_instr->src_operand.size;
261 PrintDebug("Dst_Addr = %p, SRC operand = %p\n",
262 (void *)em_dst_addr, (void *)em_src_addr);
265 if (read_fn(info, read_gpa, (void *)src_addr, src_op_len, priv_data) != src_op_len) {
266 PrintError("Did not fully read hooked data\n");
270 if (run_op(info, dec_instr->op_type, em_src_addr, em_dst_addr, src_op_len, dst_op_len) == -1) {
271 PrintError("Instruction Emulation Failed\n");
275 if (write_fn(info, read_gpa, (void *)src_addr, dst_op_len, priv_data) != dst_op_len) {
276 PrintError("Did not fully write hooked data\n");
280 info->rip += dec_instr->instr_length;
288 int v3_emulate_write_op(struct guest_info * info, addr_t write_gva, addr_t write_gpa, addr_t dst_addr,
289 int (*write_fn)(struct guest_info * core, addr_t guest_addr, void * src, uint_t length, void * priv_data),
291 struct x86_instr dec_instr;
298 PrintDebug("Emulating Write for instruction at %p\n", (void *)(addr_t)(info->rip));
299 PrintDebug("GVA=%p Dst_Addr=%p\n", (void *)write_gva, (void *)dst_addr);
301 if (info->mem_mode == PHYSICAL_MEM) {
302 ret = v3_read_gpa_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 15, instr);
304 ret = v3_read_gva_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 15, instr);
311 if (v3_decode(info, (addr_t)instr, &dec_instr) == -1) {
312 PrintError("Decoding Error\n");
313 // Kick off single step emulator
318 * Instructions needing to be special cased.... *
320 if (dec_instr.is_str_op) {
321 return emulate_string_write_op(info, &dec_instr, write_gva, write_gpa, dst_addr, write_fn, priv_data);
322 } else if (dec_instr.op_type == V3_OP_XCHG) {
323 return emulate_xchg_write_op(info, &dec_instr, write_gva, write_gpa, dst_addr, write_fn, priv_data);
327 if (info->shdw_pg_mode == SHADOW_PAGING) {
328 if ((dec_instr.dst_operand.type != MEM_OPERAND) ||
329 (dec_instr.dst_operand.operand != write_gva)) {
330 PrintError("Inconsistency between Pagefault and Instruction Decode XED_ADDR=%p, PF_ADDR=%p\n",
331 (void *)dec_instr.dst_operand.operand, (void *)write_gva);
335 //check that the operand (GVA) maps to the the faulting GPA
339 if (dec_instr.src_operand.type == MEM_OPERAND) {
340 if (info->mem_mode == PHYSICAL_MEM) {
341 if (v3_gpa_to_hva(info, dec_instr.src_operand.operand, &src_addr) == -1) {
342 PrintError("Could not translate write Source (Physical) to host VA\n");
346 if (v3_gva_to_hva(info, dec_instr.src_operand.operand, &src_addr) == -1) {
347 PrintError("Could not translate write Source (Virtual) to host VA\n");
351 } else if (dec_instr.src_operand.type == REG_OPERAND) {
352 src_addr = dec_instr.src_operand.operand;
354 src_addr = (addr_t)&(dec_instr.src_operand.operand);
357 dst_op_len = dec_instr.dst_operand.size;
358 src_op_len = dec_instr.src_operand.size;
360 PrintDebug("Dst_Addr = %p, SRC operand = %p\n",
361 (void *)dst_addr, (void *)src_addr);
364 if (run_op(info, dec_instr.op_type, src_addr, dst_addr, src_op_len, dst_op_len) == -1) {
365 PrintError("Instruction Emulation Failed\n");
369 if (write_fn(info, write_gpa, (void *)dst_addr, dst_op_len, priv_data) != dst_op_len) {
370 PrintError("Did not fully write hooked data\n");
374 info->rip += dec_instr.instr_length;
380 int v3_emulate_read_op(struct guest_info * info, addr_t read_gva, addr_t read_gpa, addr_t src_addr,
381 int (*read_fn)(struct guest_info * core, addr_t guest_addr, void * dst, uint_t length, void * priv_data),
382 int (*write_fn)(struct guest_info * core, addr_t guest_addr, void * src, uint_t length, void * priv_data),
384 struct x86_instr dec_instr;
391 PrintDebug("Emulating Read for instruction at %p\n", (void *)(addr_t)(info->rip));
392 PrintDebug("GVA=%p\n", (void *)read_gva);
394 if (info->mem_mode == PHYSICAL_MEM) {
395 ret = v3_read_gpa_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 15, instr);
397 ret = v3_read_gva_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 15, instr);
401 PrintError("Could not read instruction for Emulated Read at %p\n", (void *)(addr_t)(info->rip));
406 if (v3_decode(info, (addr_t)instr, &dec_instr) == -1) {
407 PrintError("Decoding Error\n");
408 // Kick off single step emulator
412 if (dec_instr.is_str_op) {
413 PrintError("String operations not implemented on fully hooked regions\n");
415 } else if (dec_instr.op_type == V3_OP_XCHG) {
416 return emulate_xchg_read_op(info, &dec_instr, read_gva, read_gpa, src_addr, read_fn, write_fn, priv_data);
419 if (info->shdw_pg_mode == SHADOW_PAGING) {
420 if ((dec_instr.src_operand.type != MEM_OPERAND) ||
421 (dec_instr.src_operand.operand != read_gva)) {
422 PrintError("Inconsistency between Pagefault and Instruction Decode XED_ADDR=%p, PF_ADDR=%p operand_type=%d\n",
423 (void *)dec_instr.src_operand.operand, (void *)read_gva, dec_instr.src_operand.type);
427 //check that the operand (GVA) maps to the the faulting GPA
430 if (dec_instr.dst_operand.type == MEM_OPERAND) {
431 if (info->mem_mode == PHYSICAL_MEM) {
432 if (v3_gpa_to_hva(info, dec_instr.dst_operand.operand, &dst_addr) == -1) {
433 PrintError("Could not translate Read Destination (Physical) to host VA\n");
437 if (v3_gva_to_hva(info, dec_instr.dst_operand.operand, &dst_addr) == -1) {
438 PrintError("Could not translate Read Destination (Virtual) to host VA\n");
442 } else if (dec_instr.dst_operand.type == REG_OPERAND) {
443 dst_addr = dec_instr.dst_operand.operand;
445 dst_addr = (addr_t)&(dec_instr.dst_operand.operand);
448 src_op_len = dec_instr.src_operand.size;
449 dst_op_len = dec_instr.dst_operand.size;
451 PrintDebug("Dst_Addr = %p, SRC Addr = %p\n",
452 (void *)dst_addr, (void *)src_addr);
454 if (read_fn(info, read_gpa, (void *)src_addr, src_op_len, priv_data) != src_op_len) {
455 PrintError("Did not fully read hooked data\n");
459 if (run_op(info, dec_instr.op_type, src_addr, dst_addr, src_op_len, dst_op_len) == -1) {
460 PrintError("Instruction Emulation Failed\n");
464 info->rip += dec_instr.instr_length;
474 static int run_op(struct guest_info * info, v3_op_type_t op_type, addr_t src_addr, addr_t dst_addr, int src_op_size, int dst_op_size) {
476 if (src_op_size == 1) {
477 PrintDebug("Executing 8 bit instruction\n");
481 adc8((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
484 add8((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
487 and8((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
490 or8((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
493 xor8((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
496 sub8((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
500 mov8((addr_t *)dst_addr, (addr_t *)src_addr);
504 movzx8((addr_t *)dst_addr, (addr_t *)src_addr, dst_op_size);
507 movsx8((addr_t *)dst_addr, (addr_t *)src_addr, dst_op_size);
511 not8((addr_t *)dst_addr);
514 xchg8((addr_t *)dst_addr, (addr_t *)src_addr);
519 inc8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
522 dec8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
525 neg8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
528 setb8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
531 setbe8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
534 setl8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
537 setle8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
540 setnb8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
543 setnbe8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
546 setnl8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
549 setnle8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
552 setno8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
555 setnp8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
558 setns8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
561 setnz8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
564 seto8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
567 setp8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
570 sets8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
573 setz8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
577 PrintError("Unknown 8 bit instruction\n");
581 } else if (src_op_size == 2) {
582 PrintDebug("Executing 16 bit instruction\n");
586 adc16((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
589 add16((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
592 and16((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
595 or16((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
598 xor16((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
601 sub16((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
606 inc16((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
609 dec16((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
612 neg16((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
616 mov16((addr_t *)dst_addr, (addr_t *)src_addr);
619 movzx16((addr_t *)dst_addr, (addr_t *)src_addr, dst_op_size);
622 movsx16((addr_t *)dst_addr, (addr_t *)src_addr, dst_op_size);
625 not16((addr_t *)dst_addr);
628 xchg16((addr_t *)dst_addr, (addr_t *)src_addr);
632 PrintError("Unknown 16 bit instruction\n");
636 } else if (src_op_size == 4) {
637 PrintDebug("Executing 32 bit instruction\n");
641 adc32((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
644 add32((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
647 and32((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
650 or32((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
653 xor32((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
656 sub32((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
660 inc32((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
663 dec32((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
666 neg32((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
670 mov32((addr_t *)dst_addr, (addr_t *)src_addr);
674 not32((addr_t *)dst_addr);
677 xchg32((addr_t *)dst_addr, (addr_t *)src_addr);
681 PrintError("Unknown 32 bit instruction\n");
686 } else if (src_op_size == 8) {
687 PrintDebug("Executing 64 bit instruction\n");
691 adc64((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
694 add64((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
697 and64((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
700 or64((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
703 xor64((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
706 sub64((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
710 inc64((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
713 dec64((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
716 neg64((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
720 mov64((addr_t *)dst_addr, (addr_t *)src_addr);
724 not64((addr_t *)dst_addr);
727 xchg64((addr_t *)dst_addr, (addr_t *)src_addr);
731 PrintError("Unknown 64 bit instruction\n");
737 PrintError("Invalid Operation Size\n");