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 (info->shdw_pg_mode == SHADOW_PAGING) {
46 if (dec_instr->dst_operand.operand != write_gva) {
47 PrintError("Inconsistency between Pagefault and Instruction Decode XED_ADDR=%p, PF_ADDR=%p\n",
48 (void *)dec_instr->dst_operand.operand, (void *)write_gva);
52 // Nested paging (Need check??)
55 /*emulation_length = ( (dec_instr->str_op_length < (0x1000 - PAGE_OFFSET_4KB(write_gva))) ?
56 dec_instr->str_op_length :
57 (0x1000 - PAGE_OFFSET_4KB(write_gva)));*/
58 emulation_length = ( (dec_instr->str_op_length * (dec_instr->dst_operand.size) < (0x1000 - PAGE_OFFSET_4KB(write_gva))) ?
59 dec_instr->str_op_length * dec_instr->dst_operand.size :
60 (0x1000 - PAGE_OFFSET_4KB(write_gva)));
62 /* ** Fix emulation length so that it doesn't overrun over the src page either ** */
63 emulation_iter_cnt = emulation_length / dec_instr->dst_operand.size;
64 tmp_rcx = emulation_iter_cnt;
66 if (dec_instr->op_type == V3_OP_MOVS) {
68 // figure out addresses here....
69 if (info->mem_mode == PHYSICAL_MEM) {
70 if (v3_gpa_to_hva(info, dec_instr->src_operand.operand, &src_addr) == -1) {
71 PrintError("Could not translate write Source (Physical) to host VA\n");
75 if (v3_gva_to_hva(info, dec_instr->src_operand.operand, &src_addr) == -1) {
76 PrintError("Could not translate write Source (Virtual) to host VA\n");
81 if (dec_instr->dst_operand.size == 1) {
82 movs8((addr_t *)&dst_addr, &src_addr, &tmp_rcx, (addr_t *)&(info->ctrl_regs.rflags));
83 } else if (dec_instr->dst_operand.size == 2) {
84 movs16((addr_t *)&dst_addr, &src_addr, &tmp_rcx, (addr_t *)&(info->ctrl_regs.rflags));
85 } else if (dec_instr->dst_operand.size == 4) {
86 movs32((addr_t *)&dst_addr, &src_addr, &tmp_rcx, (addr_t *)&(info->ctrl_regs.rflags));
88 } else if (dec_instr->dst_operand.size == 8) {
89 movs64((addr_t *)&dst_addr, &src_addr, &tmp_rcx, (addr_t *)&(info->ctrl_regs.rflags));
92 PrintError("Invalid operand length\n");
96 info->vm_regs.rdi += emulation_length;
97 info->vm_regs.rsi += emulation_length;
99 // RCX is only modified if the rep prefix is present
100 if (dec_instr->prefixes.rep == 1) {
101 info->vm_regs.rcx -= emulation_iter_cnt;
104 } else if (dec_instr->op_type == V3_OP_STOS) {
106 if (dec_instr->dst_operand.size == 1) {
107 stos8((addr_t *)&dst_addr, (addr_t *)&(info->vm_regs.rax), &tmp_rcx, (addr_t *)&(info->ctrl_regs.rflags));
108 } else if (dec_instr->dst_operand.size == 2) {
109 stos16((addr_t *)&dst_addr, (addr_t *)&(info->vm_regs.rax), &tmp_rcx, (addr_t *)&(info->ctrl_regs.rflags));
110 } else if (dec_instr->dst_operand.size == 4) {
111 stos32((addr_t *)&dst_addr, (addr_t *)&(info->vm_regs.rax), &tmp_rcx, (addr_t *)&(info->ctrl_regs.rflags));
113 } else if (dec_instr->dst_operand.size == 8) {
114 stos64((addr_t *)&dst_addr, (addr_t *)&(info->vm_regs.rax), &tmp_rcx, (addr_t *)&(info->ctrl_regs.rflags));
117 PrintError("Invalid operand length\n");
121 info->vm_regs.rdi += emulation_length;
123 // RCX is only modified if the rep prefix is present
124 if (dec_instr->prefixes.rep == 1) {
125 info->vm_regs.rcx -= emulation_iter_cnt;
129 PrintError("Unimplemented String operation\n");
133 if (write_fn(info, write_gpa, (void *)dst_addr, emulation_length, priv_data) != emulation_length) {
134 PrintError("Did not fully read hooked data\n");
138 if (emulation_length == dec_instr->str_op_length) {
139 info->rip += dec_instr->instr_length;
142 return emulation_length;
146 static int emulate_xchg_write_op(struct guest_info * info, struct x86_instr * dec_instr,
147 addr_t write_gva, addr_t write_gpa, addr_t dst_addr,
148 int (*write_fn)(struct guest_info * core, addr_t guest_addr, void * src, uint_t length, void * priv_data),
151 addr_t em_dst_addr = 0;
154 PrintDebug("Emulating XCHG write\n");
156 if (dec_instr->src_operand.type == MEM_OPERAND) {
157 if (info->shdw_pg_mode == SHADOW_PAGING) {
158 if (dec_instr->src_operand.operand != write_gva) {
159 PrintError("XCHG: Inconsistency between Pagefault and Instruction Decode XED_ADDR=%p, PF_ADDR=%p\n",
160 (void *)dec_instr->src_operand.operand, (void *)write_gva);
166 } else if (dec_instr->src_operand.type == REG_OPERAND) {
167 src_addr = dec_instr->src_operand.operand;
169 src_addr = (addr_t)&(dec_instr->src_operand.operand);
174 if (dec_instr->dst_operand.type == MEM_OPERAND) {
175 if (info->shdw_pg_mode == SHADOW_PAGING) {
176 if (dec_instr->dst_operand.operand != write_gva) {
177 PrintError("XCHG: Inconsistency between Pagefault and Instruction Decode XED_ADDR=%p, PF_ADDR=%p\n",
178 (void *)dec_instr->dst_operand.operand, (void *)write_gva);
182 //check that the operand (GVA) maps to the the faulting GPA
185 em_dst_addr = dst_addr;
186 } else if (dec_instr->src_operand.type == REG_OPERAND) {
187 em_dst_addr = dec_instr->src_operand.operand;
189 em_dst_addr = (addr_t)&(dec_instr->src_operand.operand);
192 dst_op_len = dec_instr->dst_operand.size;
193 src_op_len = dec_instr->src_operand.size;
195 PrintDebug("Dst_Addr = %p, SRC operand = %p\n",
196 (void *)dst_addr, (void *)src_addr);
199 if (run_op(info, dec_instr->op_type, src_addr, em_dst_addr, src_op_len, dst_op_len) == -1) {
200 PrintError("Instruction Emulation Failed\n");
204 if (write_fn(info, write_gpa, (void *)dst_addr, dst_op_len, priv_data) != dst_op_len) {
205 PrintError("Did not fully write hooked data\n");
209 info->rip += dec_instr->instr_length;
216 static int emulate_xchg_read_op(struct guest_info * info, struct x86_instr * dec_instr,
217 addr_t read_gva, addr_t read_gpa, addr_t src_addr,
218 int (*read_fn)(struct guest_info * core, addr_t guest_addr, void * dst, uint_t length, void * priv_data),
219 int (*write_fn)(struct guest_info * core, addr_t guest_addr, void * src, uint_t length, void * priv_data),
221 addr_t em_src_addr = 0;
222 addr_t em_dst_addr = 0;
226 PrintDebug("Emulating XCHG Read\n");
228 if (dec_instr->src_operand.type == MEM_OPERAND) {
229 if (dec_instr->src_operand.operand != read_gva) {
230 PrintError("XCHG: Inconsistency between Pagefault and Instruction Decode XED_ADDR=%p, PF_ADDR=%p\n",
231 (void *)dec_instr->src_operand.operand, (void *)read_gva);
235 em_src_addr = src_addr;
236 } else if (dec_instr->src_operand.type == REG_OPERAND) {
237 em_src_addr = dec_instr->src_operand.operand;
239 em_src_addr = (addr_t)&(dec_instr->src_operand.operand);
244 if (dec_instr->dst_operand.type == MEM_OPERAND) {
245 if (info->shdw_pg_mode == SHADOW_PAGING) {
246 if (dec_instr->dst_operand.operand != read_gva) {
247 PrintError("XCHG: Inconsistency between Pagefault and Instruction Decode XED_ADDR=%p, PF_ADDR=%p\n",
248 (void *)dec_instr->dst_operand.operand, (void *)read_gva);
252 //check that the operand (GVA) maps to the the faulting GPA
255 em_dst_addr = src_addr;
256 } else if (dec_instr->src_operand.type == REG_OPERAND) {
257 em_dst_addr = dec_instr->src_operand.operand;
259 em_dst_addr = (addr_t)&(dec_instr->src_operand.operand);
262 dst_op_len = dec_instr->dst_operand.size;
263 src_op_len = dec_instr->src_operand.size;
265 PrintDebug("Dst_Addr = %p, SRC operand = %p\n",
266 (void *)em_dst_addr, (void *)em_src_addr);
269 if (read_fn(info, read_gpa, (void *)src_addr, src_op_len, priv_data) != src_op_len) {
270 PrintError("Did not fully read hooked data\n");
274 if (run_op(info, dec_instr->op_type, em_src_addr, em_dst_addr, src_op_len, dst_op_len) == -1) {
275 PrintError("Instruction Emulation Failed\n");
279 if (write_fn(info, read_gpa, (void *)src_addr, dst_op_len, priv_data) != dst_op_len) {
280 PrintError("Did not fully write hooked data\n");
284 info->rip += dec_instr->instr_length;
292 int v3_emulate_write_op(struct guest_info * info, addr_t write_gva, addr_t write_gpa, addr_t dst_addr,
293 int (*write_fn)(struct guest_info * core, addr_t guest_addr, void * src, uint_t length, void * priv_data),
295 struct x86_instr dec_instr;
302 PrintDebug("Emulating Write for instruction at %p\n", (void *)(addr_t)(info->rip));
303 PrintDebug("GVA=%p Dst_Addr=%p\n", (void *)write_gva, (void *)dst_addr);
305 if (info->mem_mode == PHYSICAL_MEM) {
306 ret = v3_read_gpa_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 15, instr);
308 ret = v3_read_gva_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 15, instr);
315 if (v3_decode(info, (addr_t)instr, &dec_instr) == -1) {
316 PrintError("Decoding Error\n");
317 // Kick off single step emulator
322 * Instructions needing to be special cased.... *
324 if (dec_instr.is_str_op) {
325 return emulate_string_write_op(info, &dec_instr, write_gva, write_gpa, dst_addr, write_fn, priv_data);
326 } else if (dec_instr.op_type == V3_OP_XCHG) {
327 return emulate_xchg_write_op(info, &dec_instr, write_gva, write_gpa, dst_addr, write_fn, priv_data);
331 if (info->shdw_pg_mode == SHADOW_PAGING) {
332 if ((dec_instr.dst_operand.type != MEM_OPERAND) ||
333 (dec_instr.dst_operand.operand != write_gva)) {
334 PrintError("Inconsistency between Pagefault and Instruction Decode XED_ADDR=%p, PF_ADDR=%p\n",
335 (void *)dec_instr.dst_operand.operand, (void *)write_gva);
339 //check that the operand (GVA) maps to the the faulting GPA
343 if (dec_instr.src_operand.type == MEM_OPERAND) {
344 if (info->mem_mode == PHYSICAL_MEM) {
345 if (v3_gpa_to_hva(info, dec_instr.src_operand.operand, &src_addr) == -1) {
346 PrintError("Could not translate write Source (Physical) to host VA\n");
350 if (v3_gva_to_hva(info, dec_instr.src_operand.operand, &src_addr) == -1) {
351 PrintError("Could not translate write Source (Virtual) to host VA\n");
355 } else if (dec_instr.src_operand.type == REG_OPERAND) {
356 src_addr = dec_instr.src_operand.operand;
358 src_addr = (addr_t)&(dec_instr.src_operand.operand);
361 dst_op_len = dec_instr.dst_operand.size;
362 src_op_len = dec_instr.src_operand.size;
364 PrintDebug("Dst_Addr = %p, SRC operand = %p\n",
365 (void *)dst_addr, (void *)src_addr);
368 if (run_op(info, dec_instr.op_type, src_addr, dst_addr, src_op_len, dst_op_len) == -1) {
369 PrintError("Instruction Emulation Failed\n");
373 if (write_fn(info, write_gpa, (void *)dst_addr, dst_op_len, priv_data) != dst_op_len) {
374 PrintError("Did not fully write hooked data\n");
378 info->rip += dec_instr.instr_length;
384 int v3_emulate_read_op(struct guest_info * info, addr_t read_gva, addr_t read_gpa, addr_t src_addr,
385 int (*read_fn)(struct guest_info * core, addr_t guest_addr, void * dst, uint_t length, void * priv_data),
386 int (*write_fn)(struct guest_info * core, addr_t guest_addr, void * src, uint_t length, void * priv_data),
388 struct x86_instr dec_instr;
395 PrintDebug("Emulating Read for instruction at %p\n", (void *)(addr_t)(info->rip));
396 PrintDebug("GVA=%p\n", (void *)read_gva);
398 if (info->mem_mode == PHYSICAL_MEM) {
399 ret = v3_read_gpa_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 15, instr);
401 ret = v3_read_gva_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 15, instr);
405 PrintError("Could not read instruction for Emulated Read at %p\n", (void *)(addr_t)(info->rip));
410 if (v3_decode(info, (addr_t)instr, &dec_instr) == -1) {
411 PrintError("Decoding Error\n");
412 // Kick off single step emulator
416 if (dec_instr.is_str_op) {
417 PrintError("String operations not implemented on fully hooked regions\n");
419 } else if (dec_instr.op_type == V3_OP_XCHG) {
420 return emulate_xchg_read_op(info, &dec_instr, read_gva, read_gpa, src_addr, read_fn, write_fn, priv_data);
423 if (info->shdw_pg_mode == SHADOW_PAGING) {
424 if ((dec_instr.src_operand.type != MEM_OPERAND) ||
425 (dec_instr.src_operand.operand != read_gva)) {
426 PrintError("Inconsistency between Pagefault and Instruction Decode XED_ADDR=%p, PF_ADDR=%p operand_type=%d\n",
427 (void *)dec_instr.src_operand.operand, (void *)read_gva, dec_instr.src_operand.type);
431 //check that the operand (GVA) maps to the the faulting GPA
434 if (dec_instr.dst_operand.type == MEM_OPERAND) {
435 if (info->mem_mode == PHYSICAL_MEM) {
436 if (v3_gpa_to_hva(info, dec_instr.dst_operand.operand, &dst_addr) == -1) {
437 PrintError("Could not translate Read Destination (Physical) to host VA\n");
441 if (v3_gva_to_hva(info, dec_instr.dst_operand.operand, &dst_addr) == -1) {
442 PrintError("Could not translate Read Destination (Virtual) to host VA\n");
446 } else if (dec_instr.dst_operand.type == REG_OPERAND) {
447 dst_addr = dec_instr.dst_operand.operand;
449 dst_addr = (addr_t)&(dec_instr.dst_operand.operand);
452 src_op_len = dec_instr.src_operand.size;
453 dst_op_len = dec_instr.dst_operand.size;
455 PrintDebug("Dst_Addr = %p, SRC Addr = %p\n",
456 (void *)dst_addr, (void *)src_addr);
458 if (read_fn(info, read_gpa, (void *)src_addr, src_op_len, priv_data) != src_op_len) {
459 PrintError("Did not fully read hooked data\n");
463 if (run_op(info, dec_instr.op_type, src_addr, dst_addr, src_op_len, dst_op_len) == -1) {
464 PrintError("Instruction Emulation Failed\n");
468 info->rip += dec_instr.instr_length;
478 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) {
480 if (src_op_size == 1) {
481 PrintDebug("Executing 8 bit instruction\n");
485 adc8((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
488 add8((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
491 and8((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
494 or8((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
497 xor8((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
500 sub8((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
504 mov8((addr_t *)dst_addr, (addr_t *)src_addr);
508 movzx8((addr_t *)dst_addr, (addr_t *)src_addr, dst_op_size);
511 movsx8((addr_t *)dst_addr, (addr_t *)src_addr, dst_op_size);
515 not8((addr_t *)dst_addr);
518 xchg8((addr_t *)dst_addr, (addr_t *)src_addr);
523 inc8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
526 dec8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
529 neg8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
532 setb8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
535 setbe8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
538 setl8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
541 setle8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
544 setnb8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
547 setnbe8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
550 setnl8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
553 setnle8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
556 setno8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
559 setnp8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
562 setns8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
565 setnz8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
568 seto8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
571 setp8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
574 sets8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
577 setz8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
581 PrintError("Unknown 8 bit instruction\n");
585 } else if (src_op_size == 2) {
586 PrintDebug("Executing 16 bit instruction\n");
590 adc16((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
593 add16((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
596 and16((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
599 or16((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
602 xor16((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
605 sub16((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
610 inc16((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
613 dec16((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
616 neg16((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
620 mov16((addr_t *)dst_addr, (addr_t *)src_addr);
623 movzx16((addr_t *)dst_addr, (addr_t *)src_addr, dst_op_size);
626 movsx16((addr_t *)dst_addr, (addr_t *)src_addr, dst_op_size);
629 not16((addr_t *)dst_addr);
632 xchg16((addr_t *)dst_addr, (addr_t *)src_addr);
636 PrintError("Unknown 16 bit instruction\n");
640 } else if (src_op_size == 4) {
641 PrintDebug("Executing 32 bit instruction\n");
645 adc32((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
648 add32((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
651 and32((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
654 or32((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
657 xor32((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
660 sub32((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
664 inc32((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
667 dec32((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
670 neg32((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
674 mov32((addr_t *)dst_addr, (addr_t *)src_addr);
678 not32((addr_t *)dst_addr);
681 xchg32((addr_t *)dst_addr, (addr_t *)src_addr);
685 PrintError("Unknown 32 bit instruction\n");
690 } else if (src_op_size == 8) {
691 PrintDebug("Executing 64 bit instruction\n");
695 adc64((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
698 add64((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
701 and64((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
704 or64((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
707 xor64((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
710 sub64((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
714 inc64((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
717 dec64((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
720 neg64((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
724 mov64((addr_t *)dst_addr, (addr_t *)src_addr);
728 not64((addr_t *)dst_addr);
731 xchg64((addr_t *)dst_addr, (addr_t *)src_addr);
735 PrintError("Unknown 64 bit instruction\n");
741 PrintError("Invalid Operation Size\n");