Palacios Public Git Repository

To checkout Palacios execute

  git clone http://v3vee.org/palacios/palacios.web/palacios.git
This will give you the master branch. You probably want the devel branch or one of the release branches. To switch to the devel branch, simply execute
  cd palacios
  git checkout --track -b devel origin/devel
The other branches are similar.


fixed string rcx size error
[palacios.git] / palacios / src / palacios / vmm_emulator.c
1 /* 
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.  
5  *
6  * The V3VEE Project is a joint project between Northwestern University
7  * and the University of New Mexico.  You can find out more at 
8  * http://www.v3vee.org
9  *
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.
13  *
14  * Author: Jack Lange <jarusl@cs.northwestern.edu>
15  *
16  * This is free software.  You are permitted to use,
17  * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
18  */
19
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>
26
27 #ifndef DEBUG_EMULATOR
28 #undef PrintDebug
29 #define PrintDebug(fmt, args...)
30 #endif
31
32
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);
34
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)(addr_t guest_addr, void * src, uint_t length, void * priv_data), 
39                                    void * priv_data) {
40     uint_t emulation_length = 0;
41     addr_t tmp_rcx = 0;
42     addr_t src_addr = 0;
43
44     if (dec_instr->dst_operand.operand != write_gva) {
45         PrintError("Inconsistency between Pagefault and Instruction Decode XED_ADDR=%p, PF_ADDR=%p\n",
46                    (void *)dec_instr->dst_operand.operand, (void *)write_gva);
47         return -1;
48     }
49   
50     emulation_length = ( (dec_instr->str_op_length  < (0x1000 - PAGE_OFFSET_4KB(write_gva))) ? 
51                          dec_instr->str_op_length :
52                          (0x1000 - PAGE_OFFSET_4KB(write_gva)));
53   
54     /* ** Fix emulation length so that it doesn't overrun over the src page either ** */
55     tmp_rcx = emulation_length / dec_instr->dst_operand.size;
56   
57     if (dec_instr->op_type == V3_OP_MOVS) {
58
59         // figure out addresses here....
60         if (info->mem_mode == PHYSICAL_MEM) {
61             if (guest_pa_to_host_va(info, dec_instr->src_operand.operand, &src_addr) == -1) {
62                 PrintError("Could not translate write Source (Physical) to host VA\n");
63                 return -1;
64             }
65         } else {
66             if (guest_va_to_host_va(info, dec_instr->src_operand.operand, &src_addr) == -1) {
67                 PrintError("Could not translate write Source (Virtual) to host VA\n");
68                 return -1;
69             }
70         }
71
72         if (dec_instr->dst_operand.size == 1) {
73             movs8((addr_t *)&dst_addr, &src_addr, &tmp_rcx, (addr_t *)&(info->ctrl_regs.rflags));
74         } else if (dec_instr->dst_operand.size == 2) {
75             movs16((addr_t *)&dst_addr, &src_addr, &tmp_rcx, (addr_t *)&(info->ctrl_regs.rflags));
76         } else if (dec_instr->dst_operand.size == 4) {
77             movs32((addr_t *)&dst_addr, &src_addr, &tmp_rcx, (addr_t *)&(info->ctrl_regs.rflags));
78 #ifdef __V3_64BIT__
79         } else if (dec_instr->dst_operand.size == 8) {
80             movs64((addr_t *)&dst_addr, &src_addr, &tmp_rcx, (addr_t *)&(info->ctrl_regs.rflags));
81 #endif
82         } else {
83             PrintError("Invalid operand length\n");
84             return -1;
85         }
86
87         info->vm_regs.rdi += emulation_length;
88         info->vm_regs.rsi += emulation_length;
89
90         // RCX is only modified if the rep prefix is present
91         if (dec_instr->prefixes.rep == 1) {
92             info->vm_regs.rcx -= emulation_length;
93         }
94
95     } else if (dec_instr->op_type == V3_OP_STOS) {
96
97         if (dec_instr->dst_operand.size == 1) {
98             stos8((addr_t *)&dst_addr, (addr_t  *)&(info->vm_regs.rax), &tmp_rcx, (addr_t *)&(info->ctrl_regs.rflags));
99         } else if (dec_instr->dst_operand.size == 2) {
100             stos16((addr_t *)&dst_addr, (addr_t  *)&(info->vm_regs.rax), &tmp_rcx, (addr_t *)&(info->ctrl_regs.rflags));
101         } else if (dec_instr->dst_operand.size == 4) {
102             stos32((addr_t *)&dst_addr, (addr_t  *)&(info->vm_regs.rax), &tmp_rcx, (addr_t *)&(info->ctrl_regs.rflags));
103 #ifdef __V3_64BIT__
104         } else if (dec_instr->dst_operand.size == 8) {
105             stos64((addr_t *)&dst_addr, (addr_t  *)&(info->vm_regs.rax), &tmp_rcx, (addr_t *)&(info->ctrl_regs.rflags));
106 #endif
107         } else {
108             PrintError("Invalid operand length\n");
109             return -1;
110         }
111
112         info->vm_regs.rdi += emulation_length;
113     
114         // RCX is only modified if the rep prefix is present
115         if (dec_instr->prefixes.rep == 1) {
116             info->vm_regs.rcx -= emulation_length;
117         }
118
119     } else {
120         PrintError("Unimplemented String operation\n");
121         return -1;
122     }
123
124     if (write_fn(write_gpa, (void *)dst_addr, emulation_length, priv_data) != emulation_length) {
125         PrintError("Did not fully read hooked data\n");
126         return -1;
127     }
128
129     if (emulation_length == dec_instr->str_op_length) {
130         info->rip += dec_instr->instr_length;
131     }
132
133     return emulation_length;
134 }
135
136
137 static int emulate_xchg_write_op(struct guest_info * info, struct x86_instr * dec_instr, 
138                                  addr_t write_gva, addr_t write_gpa, addr_t dst_addr, 
139                                  int (*write_fn)(addr_t guest_addr, void * src, uint_t length, void * priv_data), 
140                                  void * priv_data) {
141     addr_t src_addr = 0;
142     addr_t em_dst_addr = 0;
143     int src_op_len = 0;
144     int dst_op_len = 0;  
145     PrintDebug("Emulating XCHG write\n");
146
147     if (dec_instr->src_operand.type == MEM_OPERAND) {
148         if (info->shdw_pg_mode == SHADOW_PAGING) {
149             if (dec_instr->src_operand.operand != write_gva) {
150                 PrintError("XCHG: Inconsistency between Pagefault and Instruction Decode XED_ADDR=%p, PF_ADDR=%p\n",
151                            (void *)dec_instr->src_operand.operand, (void *)write_gva);
152                 return -1;
153             }
154         }
155
156         src_addr = dst_addr;
157     } else if (dec_instr->src_operand.type == REG_OPERAND) {
158         src_addr = dec_instr->src_operand.operand;
159     } else {
160         src_addr = (addr_t)&(dec_instr->src_operand.operand);
161     }
162
163
164
165     if (dec_instr->dst_operand.type == MEM_OPERAND) {
166         if (info->shdw_pg_mode == SHADOW_PAGING) {
167             if (dec_instr->dst_operand.operand != write_gva) {
168                 PrintError("XCHG: Inconsistency between Pagefault and Instruction Decode XED_ADDR=%p, PF_ADDR=%p\n",
169                            (void *)dec_instr->dst_operand.operand, (void *)write_gva);
170                 return -1;
171             }
172         } else {
173             //check that the operand (GVA) maps to the the faulting GPA
174         }
175         
176         em_dst_addr = dst_addr;
177     } else if (dec_instr->src_operand.type == REG_OPERAND) {
178         em_dst_addr = dec_instr->src_operand.operand;
179     } else {
180         em_dst_addr = (addr_t)&(dec_instr->src_operand.operand);
181     }
182     
183     dst_op_len = dec_instr->dst_operand.size;
184     src_op_len = dec_instr->src_operand.size;
185     
186     PrintDebug("Dst_Addr = %p, SRC operand = %p\n", 
187                (void *)dst_addr, (void *)src_addr);
188     
189     
190     if (run_op(info, dec_instr->op_type, src_addr, em_dst_addr, src_op_len, dst_op_len) == -1) {
191         PrintError("Instruction Emulation Failed\n");
192         return -1;
193     }
194     
195     if (write_fn(write_gpa, (void *)dst_addr, dst_op_len, priv_data) != dst_op_len) {
196         PrintError("Did not fully write hooked data\n");
197         return -1;
198     }
199     
200     info->rip += dec_instr->instr_length;
201     
202     return dst_op_len;
203 }
204     
205
206
207 static int emulate_xchg_read_op(struct guest_info * info, struct x86_instr * dec_instr, 
208                                 addr_t read_gva, addr_t read_gpa, addr_t src_addr, 
209                                 int (*read_fn)(addr_t guest_addr, void * dst, uint_t length, void * priv_data), 
210                                 int (*write_fn)(addr_t guest_addr, void * src, uint_t length, void * priv_data),                        
211                                 void * priv_data) {
212     addr_t em_src_addr = 0;
213     addr_t em_dst_addr = 0;
214     int src_op_len = 0;
215     int dst_op_len = 0;
216
217     PrintDebug("Emulating XCHG Read\n");
218
219     if (dec_instr->src_operand.type == MEM_OPERAND) {
220         if (dec_instr->src_operand.operand != read_gva) {
221             PrintError("XCHG: Inconsistency between Pagefault and Instruction Decode XED_ADDR=%p, PF_ADDR=%p\n",
222                        (void *)dec_instr->src_operand.operand, (void *)read_gva);
223             return -1;
224         }
225     
226         em_src_addr = src_addr;
227     } else if (dec_instr->src_operand.type == REG_OPERAND) {
228         em_src_addr = dec_instr->src_operand.operand;
229     } else {
230         em_src_addr = (addr_t)&(dec_instr->src_operand.operand);
231     }
232
233
234
235     if (dec_instr->dst_operand.type == MEM_OPERAND) {
236         if (info->shdw_pg_mode == SHADOW_PAGING) {
237             if (dec_instr->dst_operand.operand != read_gva) {
238                 PrintError("XCHG: Inconsistency between Pagefault and Instruction Decode XED_ADDR=%p, PF_ADDR=%p\n",
239                            (void *)dec_instr->dst_operand.operand, (void *)read_gva);
240                 return -1;
241             }
242         } else {
243             //check that the operand (GVA) maps to the the faulting GPA
244         }
245
246         em_dst_addr = src_addr;
247     } else if (dec_instr->src_operand.type == REG_OPERAND) {
248         em_dst_addr = dec_instr->src_operand.operand;
249     } else {
250         em_dst_addr = (addr_t)&(dec_instr->src_operand.operand);
251     }
252
253     dst_op_len = dec_instr->dst_operand.size;
254     src_op_len = dec_instr->src_operand.size;
255
256     PrintDebug("Dst_Addr = %p, SRC operand = %p\n", 
257                (void *)em_dst_addr, (void *)em_src_addr);
258
259
260     if (read_fn(read_gpa, (void *)src_addr, src_op_len, priv_data) != src_op_len) {
261         PrintError("Did not fully read hooked data\n");
262         return -1;
263     }
264
265     if (run_op(info, dec_instr->op_type, em_src_addr, em_dst_addr, src_op_len, dst_op_len) == -1) {
266         PrintError("Instruction Emulation Failed\n");
267         return -1;
268     }
269
270     if (write_fn(read_gpa, (void *)src_addr, dst_op_len, priv_data) != dst_op_len) {
271         PrintError("Did not fully write hooked data\n");
272         return -1;
273     }
274
275     info->rip += dec_instr->instr_length;
276
277     return dst_op_len;
278 }
279
280
281
282
283 int v3_emulate_write_op(struct guest_info * info, addr_t write_gva, addr_t write_gpa,  addr_t dst_addr, 
284                         int (*write_fn)(addr_t guest_addr, void * src, uint_t length, void * priv_data), 
285                         void * priv_data) {
286     struct x86_instr dec_instr;
287     uchar_t instr[15];
288     int ret = 0;
289     addr_t src_addr = 0;
290     int src_op_len = 0;
291     int dst_op_len = 0;
292
293     PrintDebug("Emulating Write for instruction at %p\n", (void *)(addr_t)(info->rip));
294     PrintDebug("GVA=%p Dst_Addr=%p\n", (void *)write_gva, (void *)dst_addr);
295
296     if (info->mem_mode == PHYSICAL_MEM) { 
297         ret = read_guest_pa_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 15, instr);
298     } else { 
299         ret = read_guest_va_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 15, instr);
300     }
301
302     if (ret == -1) {
303         return -1;
304     }
305
306     if (v3_decode(info, (addr_t)instr, &dec_instr) == -1) {
307         PrintError("Decoding Error\n");
308         // Kick off single step emulator
309         return -1;
310     }
311   
312     /* 
313      * Instructions needing to be special cased.... *
314      */
315     if (dec_instr.is_str_op) {
316         return emulate_string_write_op(info, &dec_instr, write_gva, write_gpa, dst_addr, write_fn, priv_data);
317     } else if (dec_instr.op_type == V3_OP_XCHG) {
318         return emulate_xchg_write_op(info, &dec_instr, write_gva, write_gpa, dst_addr, write_fn, priv_data);
319     }
320
321
322     if (info->shdw_pg_mode == SHADOW_PAGING) {
323         if ((dec_instr.dst_operand.type != MEM_OPERAND) ||
324             (dec_instr.dst_operand.operand != write_gva)) {
325             PrintError("Inconsistency between Pagefault and Instruction Decode XED_ADDR=%p, PF_ADDR=%p\n",
326                        (void *)dec_instr.dst_operand.operand, (void *)write_gva);
327             return -1;
328         }
329     } else {
330         //check that the operand (GVA) maps to the the faulting GPA
331     }
332
333
334     if (dec_instr.src_operand.type == MEM_OPERAND) {
335         if (info->mem_mode == PHYSICAL_MEM) {
336             if (guest_pa_to_host_va(info, dec_instr.src_operand.operand, &src_addr) == -1) {
337                 PrintError("Could not translate write Source (Physical) to host VA\n");
338                 return -1;
339             }
340         } else {
341             if (guest_va_to_host_va(info, dec_instr.src_operand.operand, &src_addr) == -1) {
342                 PrintError("Could not translate write Source (Virtual) to host VA\n");
343                 return -1;
344             }
345         }
346     } else if (dec_instr.src_operand.type == REG_OPERAND) {
347         src_addr = dec_instr.src_operand.operand;
348     } else {
349         src_addr = (addr_t)&(dec_instr.src_operand.operand);
350     }
351
352     dst_op_len = dec_instr.dst_operand.size;
353     src_op_len = dec_instr.src_operand.size;
354
355     PrintDebug("Dst_Addr = %p, SRC operand = %p\n", 
356                (void *)dst_addr, (void *)src_addr);
357
358
359     if (run_op(info, dec_instr.op_type, src_addr, dst_addr, src_op_len, dst_op_len) == -1) {
360         PrintError("Instruction Emulation Failed\n");
361         return -1;
362     }
363
364     if (write_fn(write_gpa, (void *)dst_addr, dst_op_len, priv_data) != dst_op_len) {
365         PrintError("Did not fully write hooked data\n");
366         return -1;
367     }
368
369     info->rip += dec_instr.instr_length;
370
371     return dst_op_len;
372 }
373
374
375 int v3_emulate_read_op(struct guest_info * info, addr_t read_gva, addr_t read_gpa, addr_t src_addr,
376                        int (*read_fn)(addr_t guest_addr, void * dst, uint_t length, void * priv_data),
377                        int (*write_fn)(addr_t guest_addr, void * src, uint_t length, void * priv_data),  
378                        void * priv_data) {
379     struct x86_instr dec_instr;
380     uchar_t instr[15];
381     int ret = 0;
382     addr_t dst_addr = 0;
383     int src_op_len = 0;
384     int dst_op_len = 0;
385
386     PrintDebug("Emulating Read for instruction at %p\n", (void *)(addr_t)(info->rip));
387     PrintDebug("GVA=%p\n", (void *)read_gva);
388
389     if (info->mem_mode == PHYSICAL_MEM) { 
390         ret = read_guest_pa_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 15, instr);
391     } else { 
392         ret = read_guest_va_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 15, instr);
393     }
394     
395     if (ret == -1) {
396         PrintError("Could not read instruction for Emulated Read at %p\n", (void *)(addr_t)(info->rip));
397         return -1;
398     }
399
400
401     if (v3_decode(info, (addr_t)instr, &dec_instr) == -1) {
402         PrintError("Decoding Error\n");
403         // Kick off single step emulator
404         return -1;
405     }
406   
407     if (dec_instr.is_str_op) {
408         PrintError("String operations not implemented on fully hooked regions\n");
409         return -1;
410     } else if (dec_instr.op_type == V3_OP_XCHG) {
411         return emulate_xchg_read_op(info, &dec_instr, read_gva, read_gpa, src_addr, read_fn, write_fn, priv_data);
412     }
413
414     if (info->shdw_pg_mode == SHADOW_PAGING) {
415         if ((dec_instr.src_operand.type != MEM_OPERAND) ||
416             (dec_instr.src_operand.operand != read_gva)) {
417             PrintError("Inconsistency between Pagefault and Instruction Decode XED_ADDR=%p, PF_ADDR=%p operand_type=%d\n",
418                        (void *)dec_instr.src_operand.operand, (void *)read_gva, dec_instr.src_operand.type);
419             return -1;
420         }
421     } else {
422         //check that the operand (GVA) maps to the the faulting GPA
423     }
424
425     if (dec_instr.dst_operand.type == MEM_OPERAND) {
426         if (info->mem_mode == PHYSICAL_MEM) {
427             if (guest_pa_to_host_va(info, dec_instr.dst_operand.operand, &dst_addr) == -1) {
428                 PrintError("Could not translate Read Destination (Physical) to host VA\n");
429                 return -1;
430             }
431         } else {
432             if (guest_va_to_host_va(info, dec_instr.dst_operand.operand, &dst_addr) == -1) {
433                 PrintError("Could not translate Read Destination (Virtual) to host VA\n");
434                 return -1;
435             }
436         }
437     } else if (dec_instr.dst_operand.type == REG_OPERAND) {
438         dst_addr = dec_instr.dst_operand.operand;
439     } else {
440         dst_addr = (addr_t)&(dec_instr.dst_operand.operand);
441     }
442
443     src_op_len = dec_instr.src_operand.size;
444     dst_op_len = dec_instr.dst_operand.size;
445
446     PrintDebug("Dst_Addr = %p, SRC Addr = %p\n", 
447                (void *)dst_addr, (void *)src_addr);
448
449     if (read_fn(read_gpa, (void *)src_addr, src_op_len, priv_data) != src_op_len) {
450         PrintError("Did not fully read hooked data\n");
451         return -1;
452     }
453
454     if (run_op(info, dec_instr.op_type, src_addr, dst_addr, src_op_len, dst_op_len) == -1) {
455         PrintError("Instruction Emulation Failed\n");
456         return -1;
457     }
458
459     info->rip += dec_instr.instr_length;
460
461     return src_op_len;
462 }
463
464
465
466
467
468
469 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) {
470
471     if (src_op_size == 1) {
472         PrintDebug("Executing 8 bit instruction\n");
473
474         switch (op_type) {
475             case V3_OP_ADC:
476                 adc8((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
477                 break;
478             case V3_OP_ADD:
479                 add8((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
480                 break;
481             case V3_OP_AND:
482                 and8((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
483                 break;
484             case V3_OP_OR:
485                 or8((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
486                 break;
487             case V3_OP_XOR:
488                 xor8((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
489                 break;
490             case V3_OP_SUB:
491                 sub8((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
492                 break;
493
494             case V3_OP_MOV:
495                 mov8((addr_t *)dst_addr, (addr_t *)src_addr);
496                 break;
497
498             case V3_OP_MOVZX:
499                 movzx8((addr_t *)dst_addr, (addr_t *)src_addr, dst_op_size);
500                 break;
501             case V3_OP_MOVSX:
502                 movsx8((addr_t *)dst_addr, (addr_t *)src_addr, dst_op_size);
503                 break;
504
505             case V3_OP_NOT:
506                 not8((addr_t *)dst_addr);
507                 break;
508             case V3_OP_XCHG:
509                 xchg8((addr_t *)dst_addr, (addr_t *)src_addr);
510                 break;
511       
512
513             case V3_OP_INC:
514                 inc8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
515                 break;
516             case V3_OP_DEC:
517                 dec8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
518                 break;
519             case V3_OP_NEG:
520                 neg8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
521                 break;
522             case V3_OP_SETB:
523                 setb8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
524                 break;
525             case V3_OP_SETBE:
526                 setbe8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
527                 break;
528             case V3_OP_SETL:
529                 setl8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
530                 break;
531             case V3_OP_SETLE:
532                 setle8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
533                 break;
534             case V3_OP_SETNB:
535                 setnb8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
536                 break;
537             case V3_OP_SETNBE:
538                 setnbe8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
539                 break;
540             case V3_OP_SETNL:
541                 setnl8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
542                 break;
543             case V3_OP_SETNLE:
544                 setnle8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
545                 break;
546             case V3_OP_SETNO:
547                 setno8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
548                 break;
549             case V3_OP_SETNP:
550                 setnp8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
551                 break;
552             case V3_OP_SETNS:
553                 setns8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
554                 break;
555             case V3_OP_SETNZ:
556                 setnz8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
557                 break;
558             case V3_OP_SETO:
559                 seto8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
560                 break;
561             case V3_OP_SETP:
562                 setp8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
563                 break;
564             case V3_OP_SETS:
565                 sets8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
566                 break;
567             case V3_OP_SETZ:
568                 setz8((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
569                 break;
570
571             default:
572                 PrintError("Unknown 8 bit instruction\n");
573                 return -1;
574         }
575
576     } else if (src_op_size == 2) {
577         PrintDebug("Executing 16 bit instruction\n");
578
579         switch (op_type) {
580             case V3_OP_ADC:
581                 adc16((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
582                 break;
583             case V3_OP_ADD:
584                 add16((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
585                 break;
586             case V3_OP_AND:
587                 and16((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
588                 break;
589             case V3_OP_OR:
590                 or16((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
591                 break;
592             case V3_OP_XOR:
593                 xor16((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
594                 break;
595             case V3_OP_SUB:
596                 sub16((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
597                 break;
598
599
600             case V3_OP_INC:
601                 inc16((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
602                 break;
603             case V3_OP_DEC:
604                 dec16((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
605                 break;
606             case V3_OP_NEG:
607                 neg16((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
608                 break;
609
610             case V3_OP_MOV:
611                 mov16((addr_t *)dst_addr, (addr_t *)src_addr);
612                 break;
613             case V3_OP_MOVZX:
614                 movzx16((addr_t *)dst_addr, (addr_t *)src_addr, dst_op_size);
615                 break;
616             case V3_OP_MOVSX:
617                 movsx16((addr_t *)dst_addr, (addr_t *)src_addr, dst_op_size);
618                 break;
619             case V3_OP_NOT:
620                 not16((addr_t *)dst_addr);
621                 break;
622             case V3_OP_XCHG:
623                 xchg16((addr_t *)dst_addr, (addr_t *)src_addr);
624                 break;
625       
626             default:
627                 PrintError("Unknown 16 bit instruction\n");
628                 return -1;
629         }
630
631     } else if (src_op_size == 4) {
632         PrintDebug("Executing 32 bit instruction\n");
633
634         switch (op_type) {
635             case V3_OP_ADC:
636                 adc32((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
637                 break;
638             case V3_OP_ADD:
639                 add32((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
640                 break;
641             case V3_OP_AND:
642                 and32((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
643                 break;
644             case V3_OP_OR:
645                 or32((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
646                 break;
647             case V3_OP_XOR:
648                 xor32((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
649                 break;
650             case V3_OP_SUB:
651                 sub32((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
652                 break;
653
654             case V3_OP_INC:
655                 inc32((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
656                 break;
657             case V3_OP_DEC:
658                 dec32((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
659                 break;
660             case V3_OP_NEG:
661                 neg32((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
662                 break;
663
664             case V3_OP_MOV:
665                 mov32((addr_t *)dst_addr, (addr_t *)src_addr);
666                 break;
667
668             case V3_OP_NOT:
669                 not32((addr_t *)dst_addr);
670                 break;
671             case V3_OP_XCHG:
672                 xchg32((addr_t *)dst_addr, (addr_t *)src_addr);
673                 break;
674       
675             default:
676                 PrintError("Unknown 32 bit instruction\n");
677                 return -1;
678         }
679
680 #ifdef __V3_64BIT__
681     } else if (src_op_size == 8) {
682         PrintDebug("Executing 64 bit instruction\n");
683
684         switch (op_type) {
685             case V3_OP_ADC:
686                 adc64((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
687                 break;
688             case V3_OP_ADD:
689                 add64((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
690                 break;
691             case V3_OP_AND:
692                 and64((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
693                 break;
694             case V3_OP_OR:
695                 or64((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
696                 break;
697             case V3_OP_XOR:
698                 xor64((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
699                 break;
700             case V3_OP_SUB:
701                 sub64((addr_t *)dst_addr, (addr_t *)src_addr, (addr_t *)&(info->ctrl_regs.rflags));
702                 break;
703
704             case V3_OP_INC:
705                 inc64((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
706                 break;
707             case V3_OP_DEC:
708                 dec64((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
709                 break;
710             case V3_OP_NEG:
711                 neg64((addr_t *)dst_addr, (addr_t *)&(info->ctrl_regs.rflags));
712                 break;
713
714             case V3_OP_MOV:
715                 mov64((addr_t *)dst_addr, (addr_t *)src_addr);
716                 break;
717
718             case V3_OP_NOT:
719                 not64((addr_t *)dst_addr);
720                 break;
721             case V3_OP_XCHG:
722                 xchg64((addr_t *)dst_addr, (addr_t *)src_addr);
723                 break;
724       
725             default:
726                 PrintError("Unknown 64 bit instruction\n");
727                 return -1;
728         }
729 #endif
730
731     } else {
732         PrintError("Invalid Operation Size\n");
733         return -1;
734     }
735
736     return 0;
737 }