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.


68e39b04d036d0678b0b0d46cc23f5c28f367210
[palacios.git] / palacios / src / palacios / vmm_xed.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 #ifdef __DECODER_TEST__
21 #include "vmm_decoder.h"
22 #include "vmm_xed.h"
23 #include <xed/xed-interface.h>
24 #include "vm_guest.h"
25 #include "test.h"
26
27 #else
28
29 #include <palacios/vmm_decoder.h>
30 #include <palacios/vmm_xed.h>
31 #include <xed/xed-interface.h>
32 #include <palacios/vm_guest.h>
33 #include <palacios/vmm.h>
34 #endif
35
36
37
38 #ifndef DEBUG_XED
39 #undef PrintDebug
40 #define PrintDebug(fmt, args...)
41 #endif
42
43
44
45
46 static uint_t tables_inited = 0;
47
48
49 #define GPR_REGISTER     0
50 #define SEGMENT_REGISTER 1
51 #define CTRL_REGISTER    2
52 #define DEBUG_REGISTER   3
53
54
55
56 /* Disgusting mask hack...
57    I can't think right now, so we'll do it this way...
58 */
59 static const ullong_t mask_1 = 0x00000000000000ffLL;
60 static const ullong_t mask_2 = 0x000000000000ffffLL;
61 static const ullong_t mask_4 = 0x00000000ffffffffLL;
62 static const ullong_t mask_8 = 0xffffffffffffffffLL;
63
64
65 #define MASK(val, length) ({                    \
66       ullong_t mask = 0x0LL;                    \
67       switch (length) {                         \
68       case 1:                                   \
69         mask = mask_1;                          \
70         break;                                  \
71       case 2:                                   \
72         mask = mask_2;                          \
73         break;                                  \
74       case 4:                                   \
75         mask = mask_4;                          \
76         break;                                  \
77       case 8:                                   \
78         mask = mask_8;                          \
79         break;                                  \
80       }                                         \
81       val & mask;})                             \
82
83 struct memory_operand {
84   uint_t segment_size;
85   addr_t segment;
86   uint_t base_size;
87   addr_t base;
88   uint_t index_size;
89   addr_t index;
90   addr_t scale;
91   uint_t displacement_size;
92   ullong_t displacement;
93 };
94
95
96
97
98 static v3_op_type_t get_opcode(xed_iform_enum_t iform);
99
100 static int xed_reg_to_v3_reg(struct guest_info * info, xed_reg_enum_t xed_reg, addr_t * v3_reg, uint_t * reg_len);
101 static int get_memory_operand(struct guest_info * info,  xed_decoded_inst_t * xed_instr, uint_t index, struct x86_operand * operand);
102
103 static int set_decoder_mode(struct guest_info * info, xed_state_t * state) {
104   switch (info->cpu_mode) {
105   case REAL:
106     if (state->mmode != XED_MACHINE_MODE_LEGACY_16) {
107       xed_state_init(state,
108                      XED_MACHINE_MODE_LEGACY_16, 
109                      XED_ADDRESS_WIDTH_16b, 
110                      XED_ADDRESS_WIDTH_16b); 
111     }
112    break;
113   case PROTECTED:
114   case PROTECTED_PAE:
115     if (state->mmode != XED_MACHINE_MODE_LEGACY_32) {
116       xed_state_init(state,
117                      XED_MACHINE_MODE_LEGACY_32, 
118                      XED_ADDRESS_WIDTH_32b, 
119                      XED_ADDRESS_WIDTH_32b);
120     }
121     break;
122   case LONG_32_COMPAT:
123     if (state->mmode != XED_MACHINE_MODE_LONG_COMPAT_32) {
124       xed_state_init(state,
125                      XED_MACHINE_MODE_LONG_COMPAT_32, 
126                      XED_ADDRESS_WIDTH_32b, 
127                      XED_ADDRESS_WIDTH_32b);
128     }
129     break;
130   case LONG:
131     if (state->mmode != XED_MACHINE_MODE_LONG_64) {
132       PrintDebug("Setting decoder to long mode\n");
133       //      state->mmode = XED_MACHINE_MODE_LONG_64;
134       //xed_state_set_machine_mode(state, XED_MACHINE_MODE_LONG_64);
135       xed_state_init(state,
136                      XED_MACHINE_MODE_LONG_64, 
137                      XED_ADDRESS_WIDTH_64b, 
138                      XED_ADDRESS_WIDTH_64b);
139     }
140     break;
141   default:
142     PrintError("Unsupported CPU mode: %d\n", info->cpu_mode);
143     return -1;
144   }
145   return 0;
146 }
147
148 static int is_flags_reg(xed_reg_enum_t xed_reg) {
149   switch (xed_reg) {
150   case XED_REG_FLAGS:
151   case XED_REG_EFLAGS:
152   case XED_REG_RFLAGS:
153     return 1;
154   default:
155     return 0;
156   }
157 }
158
159
160
161 int v3_init_decoder(struct guest_info * info) {
162   // Global library initialization, only do it once
163   if (tables_inited == 0) {
164     xed_tables_init();
165     tables_inited = 1;
166   }
167
168   xed_state_t * decoder_state = (xed_state_t *)V3_Malloc(sizeof(xed_state_t));
169   xed_state_zero(decoder_state);
170   xed_state_init(decoder_state,
171                  XED_MACHINE_MODE_LEGACY_32, 
172                  XED_ADDRESS_WIDTH_32b, 
173                  XED_ADDRESS_WIDTH_32b);
174
175   info->decoder_state = decoder_state;
176
177   return 0;
178 }
179
180
181
182 int v3_basic_mem_decode(struct guest_info * info, addr_t instr_ptr, struct basic_instr_info * instr_info) {
183   xed_decoded_inst_t xed_instr;
184   xed_error_enum_t xed_error;
185   
186
187   if (set_decoder_mode(info, info->decoder_state) == -1) {
188     PrintError("Could not set decoder mode\n");
189     return -1;
190   }
191
192
193   xed_decoded_inst_zero_set_mode(&xed_instr, info->decoder_state);
194
195   xed_error = xed_decode(&xed_instr, 
196                          REINTERPRET_CAST(const xed_uint8_t *, instr_ptr), 
197                          XED_MAX_INSTRUCTION_BYTES);
198
199   if (xed_error != XED_ERROR_NONE) {
200     PrintError("Xed error: %s\n", xed_error_enum_t2str(xed_error));
201     return -1;
202   }
203
204   instr_info->instr_length = xed_decoded_inst_get_length(&xed_instr);
205
206
207  if (xed_decoded_inst_number_of_memory_operands(&xed_instr) == 0) {
208    PrintError("Tried to decode memory operation with no memory operands\n");
209    return -1;
210  }
211
212  instr_info->op_size = xed_decoded_inst_get_memory_operand_length(&xed_instr, 0);
213
214
215  xed_category_enum_t cat = xed_decoded_inst_get_category(&xed_instr);
216  if (cat == XED_CATEGORY_STRINGOP) {
217    instr_info->str_op = 1;
218  } else {
219    instr_info->str_op = 0;
220  }
221
222  xed_operand_values_t * operands = xed_decoded_inst_operands(&xed_instr);
223  if (xed_operand_values_has_real_rep(operands)) {
224    instr_info->has_rep = 1;
225  } else {
226    instr_info->has_rep = 0;
227  }
228
229  return 0;
230 }
231
232
233 static int decode_string_op(struct guest_info * info, 
234                             xed_decoded_inst_t * xed_instr,  const xed_inst_t * xi,
235                             struct x86_instr * instr) {
236
237   PrintDebug("String operation\n");
238
239   if (instr->op_type == V3_OP_MOVS) {
240     instr->num_operands = 2;
241
242     if (get_memory_operand(info, xed_instr, 0, &(instr->dst_operand)) == -1) {
243       PrintError("Could not get Destination memory operand\n");
244       return -1;
245     }
246
247     if (get_memory_operand(info, xed_instr, 1, &(instr->src_operand)) == -1) {
248       PrintError("Could not get Source memory operand\n");
249       return -1;
250     }
251
252     if (instr->prefixes.rep == 1) {
253       addr_t reg_addr = 0;
254       uint_t reg_length = 0;
255
256       xed_reg_to_v3_reg(info, xed_decoded_inst_get_reg(xed_instr, XED_OPERAND_REG0), &reg_addr, &reg_length);
257       instr->str_op_length = MASK(*(addr_t *)reg_addr, reg_length);
258     } else {
259       instr->str_op_length = 1;
260     }
261
262   }
263
264   return 0;
265 }
266
267
268
269 int v3_decode(struct guest_info * info, addr_t instr_ptr, struct x86_instr * instr) {
270   xed_decoded_inst_t xed_instr;
271   xed_error_enum_t xed_error;
272
273
274   v3_get_prefixes((uchar_t *)instr_ptr, &(instr->prefixes));
275
276   if (set_decoder_mode(info, info->decoder_state) == -1) {
277     PrintError("Could not set decoder mode\n");
278     return -1;
279   }
280
281   xed_decoded_inst_zero_set_mode(&xed_instr, info->decoder_state);
282
283   xed_error = xed_decode(&xed_instr, 
284                          REINTERPRET_CAST(const xed_uint8_t *, instr_ptr), 
285                          XED_MAX_INSTRUCTION_BYTES);
286
287
288   if (xed_error != XED_ERROR_NONE) {
289     PrintError("Xed error: %s\n", xed_error_enum_t2str(xed_error));
290     return -1;
291   }
292
293   const xed_inst_t * xi = xed_decoded_inst_inst(&xed_instr);
294   
295   instr->instr_length = xed_decoded_inst_get_length(&xed_instr);
296
297
298   xed_iform_enum_t iform = xed_decoded_inst_get_iform_enum(&xed_instr);
299
300 #ifdef DEBUG_XED
301   xed_iclass_enum_t iclass = xed_decoded_inst_get_iclass(&xed_instr);
302
303   PrintDebug("iform=%s, iclass=%s\n", xed_iform_enum_t2str(iform), xed_iclass_enum_t2str(iclass));
304 #endif
305
306
307   if ((instr->op_type = get_opcode(iform)) == V3_INVALID_OP) {
308     PrintError("Could not get opcode. (iform=%s)\n", xed_iform_enum_t2str(iform));
309     return -1;
310   }
311
312
313   // We special case the string operations...
314   if (xed_decoded_inst_get_category(&xed_instr) == XED_CATEGORY_STRINGOP) {
315     instr->is_str_op = 1;
316     return decode_string_op(info, &xed_instr, xi, instr); 
317   } else {
318     instr->is_str_op = 0;
319     instr->str_op_length = 0;
320   }
321
322
323   instr->num_operands = xed_decoded_inst_noperands(&xed_instr);
324
325   if (instr->num_operands > 3) {
326     PrintDebug("Special Case Not Handled\n");
327     return -1;
328     // special case
329   } else if (instr->num_operands == 3) {
330     const xed_operand_t * op = xed_inst_operand(xi, 2);
331     xed_operand_enum_t op_enum = xed_operand_name(op);
332
333     if ((!xed_operand_is_register(op_enum)) ||
334         (!is_flags_reg(xed_decoded_inst_get_reg(&xed_instr, op_enum)))) {
335       // special case
336       PrintError("Special Case not handled\n");
337       return -1;
338     }
339   }
340
341
342
343   //PrintDebug("Number of operands: %d\n", instr->num_operands);
344   //PrintDebug("INSTR length: %d\n", instr->instr_length);
345
346   // set first operand
347   if (instr->num_operands >= 1) {
348     const xed_operand_t * op = xed_inst_operand(xi, 0);
349     xed_operand_enum_t op_enum = xed_operand_name(op);
350
351     struct x86_operand * v3_op = NULL;
352
353     if (xed_operand_written(op)) {
354       v3_op = &(instr->dst_operand);
355     } else {
356       v3_op = &(instr->src_operand);
357     }
358
359
360     if (xed_operand_is_register(op_enum)) {
361       xed_reg_enum_t xed_reg =  xed_decoded_inst_get_reg(&xed_instr, op_enum);
362       int v3_reg_type = xed_reg_to_v3_reg(info, 
363                                           xed_reg, 
364                                           &(v3_op->operand), 
365                                           &(v3_op->size));
366
367       if (v3_reg_type == -1) {
368         PrintError("First operand is an Unhandled Operand: %s\n", xed_reg_enum_t2str(xed_reg));
369         v3_op->type = INVALID_OPERAND;
370         return -1;
371       } else if (v3_reg_type == SEGMENT_REGISTER) {
372         struct v3_segment * seg_reg = (struct v3_segment *)(v3_op->operand);
373         v3_op->operand = (addr_t)&(seg_reg->selector);
374       }
375
376       v3_op->type = REG_OPERAND;
377     } else {
378
379       switch (op_enum) {
380
381       case XED_OPERAND_MEM0:
382         {
383           if (get_memory_operand(info, &xed_instr, 0, v3_op) == -1) {
384             PrintError("Could not get first memory operand\n");
385             return -1;
386           }
387         }
388         break;
389
390       case XED_OPERAND_MEM1:
391       case XED_OPERAND_IMM1:
392         // illegal
393         PrintError("Illegal Operand Order\n");
394         return -1;
395
396
397       case XED_OPERAND_IMM0:
398       case XED_OPERAND_AGEN:
399       case XED_OPERAND_PTR:
400       case XED_OPERAND_RELBR:
401       default:
402         PrintError("Unhandled Operand Type\n");
403         return -1;
404
405
406       }
407     }
408   }
409
410   // set second operand
411   if (instr->num_operands >= 2) {
412     const xed_operand_t * op = xed_inst_operand(xi, 1);
413     //   xed_operand_type_enum_t op_type = xed_operand_type(op);
414     xed_operand_enum_t op_enum = xed_operand_name(op);
415     
416     struct x86_operand * v3_op;
417
418     if (xed_operand_written(op)) {
419       v3_op = &(instr->dst_operand);
420     } else {
421       v3_op = &(instr->src_operand);
422     }
423
424
425     if (xed_operand_is_register(op_enum)) {
426       xed_reg_enum_t xed_reg =  xed_decoded_inst_get_reg(&xed_instr, op_enum);
427       int v3_reg_type = xed_reg_to_v3_reg(info, 
428                                           xed_reg, 
429                                           &(v3_op->operand), 
430                                           &(v3_op->size));
431       if (v3_reg_type == -1) {
432         PrintError("Second operand is an Unhandled Operand: %s\n", xed_reg_enum_t2str(xed_reg));
433         v3_op->type = INVALID_OPERAND;
434         return -1;
435       } else if (v3_reg_type == SEGMENT_REGISTER) {
436         struct v3_segment * seg_reg = (struct v3_segment *)(v3_op->operand);
437         v3_op->operand = (addr_t)&(seg_reg->selector);
438       }
439
440       v3_op->type = REG_OPERAND;
441     
442
443     } else {
444
445       switch (op_enum) {
446
447       case XED_OPERAND_MEM0:
448         {
449           if (get_memory_operand(info, &xed_instr, 0, v3_op) == -1) {
450             PrintError("Could not get first memory operand\n");
451             return -1;
452           }
453         }
454         break;
455
456       case XED_OPERAND_IMM0:
457         {
458           instr->src_operand.size = xed_decoded_inst_get_immediate_width(&xed_instr);
459
460           if (instr->src_operand.size > 4) {
461             PrintError("Unhandled 64 bit immediates\n");
462             return -1;
463           }
464           instr->src_operand.operand = xed_decoded_inst_get_unsigned_immediate(&xed_instr);
465
466           instr->src_operand.type = IMM_OPERAND;
467
468         }
469         break;
470
471       case XED_OPERAND_MEM1:
472       case XED_OPERAND_IMM1:
473         // illegal
474         PrintError("Illegal Operand Order\n");
475         return -1;
476         
477       case XED_OPERAND_AGEN:
478       case XED_OPERAND_PTR:
479       case XED_OPERAND_RELBR:
480       default:
481         PrintError("Unhandled Operand Type\n");
482         return -1;
483       }
484     }
485
486   }
487
488   // set third operand
489   if (instr->num_operands >= 3) {
490     const xed_operand_t * op = xed_inst_operand(xi, 2);
491     xed_operand_type_enum_t op_type = xed_operand_type(op);
492     xed_operand_enum_t op_enum = xed_operand_name(op);
493
494     if (xed_operand_is_register(op_enum)) {
495       xed_reg_enum_t xed_reg =  xed_decoded_inst_get_reg(&xed_instr, op_enum);
496       int v3_reg_type = xed_reg_to_v3_reg(info, 
497                                           xed_reg, 
498                                           &(instr->third_operand.operand), 
499                                           &(instr->third_operand.size));
500
501       if (v3_reg_type == -1) {
502         PrintError("Third operand is an Unhandled Operand: %s\n", xed_reg_enum_t2str(xed_reg));
503         instr->third_operand.type = INVALID_OPERAND;
504         return -1;
505       } else if (v3_reg_type == SEGMENT_REGISTER) {
506         struct v3_segment * seg_reg = (struct v3_segment *)(instr->third_operand.operand);
507         instr->third_operand.operand = (addr_t)&(seg_reg->selector);
508       }
509
510
511       instr->third_operand.type = REG_OPERAND;
512
513
514     } else {
515       PrintError("Unhandled third operand type %s\n", xed_operand_type_enum_t2str(op_type));
516       return -1;
517     }
518
519
520   }
521
522
523
524     return 0;
525 }
526
527
528 int v3_encode(struct guest_info * info, struct x86_instr * instr, char * instr_buf) {
529
530   return -1;
531 }
532
533
534
535
536
537 static int get_memory_operand(struct guest_info * info,  xed_decoded_inst_t * xed_instr, uint_t op_index, struct x86_operand * operand) {
538   struct memory_operand mem_op;
539
540   addr_t seg;
541   addr_t base;
542   addr_t scale;
543   addr_t index;
544   ullong_t displacement;
545   // struct v3_segment * seg_reg;
546
547   PrintDebug("Xen mode = %s\n", xed_machine_mode_enum_t2str(xed_state_get_machine_mode(info->decoder_state)));
548   PrintDebug("Address width: %s\n",
549              xed_address_width_enum_t2str(xed_state_get_address_width(info->decoder_state)));
550   PrintDebug("Stack Address width: %s\n",
551              xed_address_width_enum_t2str(xed_state_get_stack_address_width(info->decoder_state)));
552
553   memset((void*)&mem_op, '\0', sizeof(struct memory_operand));
554
555   xed_reg_enum_t xed_seg = xed_decoded_inst_get_seg_reg(xed_instr, op_index);
556   if (xed_seg != XED_REG_INVALID) {
557     struct v3_segment *tmp_segment;
558     if (xed_reg_to_v3_reg(info, xed_seg, (addr_t *)&tmp_segment, &(mem_op.segment_size)) == -1) {
559       PrintError("Unhandled Segment Register\n");
560       return -1;
561     }
562     mem_op.segment = tmp_segment->base;
563   }
564
565   xed_reg_enum_t xed_base = xed_decoded_inst_get_base_reg(xed_instr, op_index);
566   if (xed_base != XED_REG_INVALID) {
567     addr_t base_reg;
568     if (xed_reg_to_v3_reg(info, xed_base, &base_reg, &(mem_op.base_size)) == -1) {
569       PrintError("Unhandled Base register\n");
570       return -1;
571     }
572     mem_op.base = *(addr_t *)base_reg;
573   }
574
575   
576
577   xed_reg_enum_t xed_idx = xed_decoded_inst_get_index_reg(xed_instr, op_index);
578   if ((op_index == 0) && (xed_idx != XED_REG_INVALID)) {
579     addr_t index_reg;
580     
581     if (xed_reg_to_v3_reg(info, xed_idx, &index_reg, &(mem_op.index_size)) == -1) {
582       PrintError("Unhandled Index Register\n");
583       return -1;
584     }
585
586     mem_op.index= *(addr_t *)index_reg;
587
588     xed_uint_t xed_scale = xed_decoded_inst_get_scale(xed_instr, op_index);
589     if (xed_scale != 0) {
590       mem_op.scale = xed_scale;
591     }
592   }
593
594
595   xed_uint_t disp_bits = xed_decoded_inst_get_memory_displacement_width(xed_instr, op_index);
596   if (disp_bits) {
597     xed_int64_t xed_disp = xed_decoded_inst_get_memory_displacement(xed_instr, op_index);
598
599     mem_op.displacement_size = disp_bits;
600     mem_op.displacement = xed_disp;
601   }
602
603   operand->type = MEM_OPERAND;
604   operand->size = xed_decoded_inst_get_memory_operand_length(xed_instr, op_index);
605   
606   
607
608   PrintDebug("Struct: Seg=%p, base=%p, index=%p, scale=%p, displacement=%p (size=%d)\n", 
609              (void *)mem_op.segment, (void*)mem_op.base, (void *)mem_op.index, 
610              (void *)mem_op.scale, (void *)(addr_t)mem_op.displacement, mem_op.displacement_size);
611
612
613   PrintDebug("operand size: %d\n", operand->size);
614
615   seg = MASK(mem_op.segment, mem_op.segment_size);
616   base = MASK(mem_op.base, mem_op.base_size);
617   index = MASK(mem_op.index, mem_op.index_size);
618   scale = mem_op.scale;
619   // displacement = MASK(mem_op.displacement, mem_op.displacement_size);
620   displacement = mem_op.displacement;
621
622   PrintDebug("Seg=%p, base=%p, index=%p, scale=%p, displacement=%p\n", 
623              (void *)seg, (void *)base, (void *)index, (void *)scale, (void *)(addr_t)displacement);
624   
625   operand->operand = seg + base + (scale * index) + displacement;
626   return 0;
627 }
628
629
630 static int xed_reg_to_v3_reg(struct guest_info * info, xed_reg_enum_t xed_reg, addr_t * v3_reg, uint_t * reg_len) {
631
632   PrintDebug("Xed Register: %s\n", xed_reg_enum_t2str(xed_reg));
633
634   switch (xed_reg) {
635   case XED_REG_INVALID:
636     *v3_reg = 0;
637     *reg_len = 0;
638     return -1;
639
640     /* 
641      * GPRs
642      */
643   case XED_REG_RAX: 
644     *v3_reg = (addr_t)&(info->vm_regs.rax);
645     *reg_len = 8;
646     return GPR_REGISTER;
647   case XED_REG_EAX:
648     *v3_reg = (addr_t)&(info->vm_regs.rax);
649     *reg_len = 4;
650     return GPR_REGISTER;
651   case XED_REG_AX:
652     *v3_reg = (addr_t)&(info->vm_regs.rax);
653     *reg_len = 2;
654     return GPR_REGISTER;
655   case XED_REG_AH:
656     *v3_reg = (addr_t)(&(info->vm_regs.rax)) + 1;
657     *reg_len = 1;
658     return GPR_REGISTER;
659   case XED_REG_AL:
660     *v3_reg = (addr_t)&(info->vm_regs.rax);
661     *reg_len = 1;
662     return GPR_REGISTER;
663
664   case XED_REG_RCX: 
665     *v3_reg = (addr_t)&(info->vm_regs.rcx);
666     *reg_len = 8;
667     return GPR_REGISTER;
668   case XED_REG_ECX:
669     *v3_reg = (addr_t)&(info->vm_regs.rcx);
670     *reg_len = 4;
671     return GPR_REGISTER;
672   case XED_REG_CX:
673     *v3_reg = (addr_t)&(info->vm_regs.rcx);
674     *reg_len = 2;
675     return GPR_REGISTER;
676   case XED_REG_CH:
677     *v3_reg = (addr_t)(&(info->vm_regs.rcx)) + 1;
678     *reg_len = 1;
679     return GPR_REGISTER;
680   case XED_REG_CL:
681     *v3_reg = (addr_t)&(info->vm_regs.rcx);
682     *reg_len = 1;
683     return GPR_REGISTER;
684
685   case XED_REG_RDX: 
686     *v3_reg = (addr_t)&(info->vm_regs.rdx);
687     *reg_len = 8;
688     return GPR_REGISTER;
689   case XED_REG_EDX:
690     *v3_reg = (addr_t)&(info->vm_regs.rdx);
691     *reg_len = 4;
692     return GPR_REGISTER;
693   case XED_REG_DX:
694     *v3_reg = (addr_t)&(info->vm_regs.rdx);
695     *reg_len = 2;
696     return GPR_REGISTER;
697   case XED_REG_DH:
698     *v3_reg = (addr_t)(&(info->vm_regs.rdx)) + 1;
699     *reg_len = 1;
700     return GPR_REGISTER;
701   case XED_REG_DL:
702     *v3_reg = (addr_t)&(info->vm_regs.rdx);
703     *reg_len = 1;
704     return GPR_REGISTER;
705
706   case XED_REG_RBX: 
707     *v3_reg = (addr_t)&(info->vm_regs.rbx);
708     *reg_len = 8;
709     return GPR_REGISTER;
710   case XED_REG_EBX:
711     *v3_reg = (addr_t)&(info->vm_regs.rbx);
712     *reg_len = 4;
713     return GPR_REGISTER;
714   case XED_REG_BX:
715     *v3_reg = (addr_t)&(info->vm_regs.rbx);
716     *reg_len = 2;
717     return GPR_REGISTER;
718   case XED_REG_BH:
719     *v3_reg = (addr_t)(&(info->vm_regs.rbx)) + 1;
720     *reg_len = 1;
721     return GPR_REGISTER;
722   case XED_REG_BL:
723     *v3_reg = (addr_t)&(info->vm_regs.rbx);
724     *reg_len = 1;
725     return GPR_REGISTER;
726
727
728   case XED_REG_RSP:
729     *v3_reg = (addr_t)&(info->vm_regs.rsp);
730     *reg_len = 8;
731     return GPR_REGISTER;
732   case XED_REG_ESP:
733     *v3_reg = (addr_t)&(info->vm_regs.rsp);
734     *reg_len = 4;
735     return GPR_REGISTER;
736   case XED_REG_SP:
737     *v3_reg = (addr_t)&(info->vm_regs.rsp);
738     *reg_len = 2;
739     return GPR_REGISTER;
740   case XED_REG_SPL:
741     *v3_reg = (addr_t)&(info->vm_regs.rsp);
742     *reg_len = 1;
743     return GPR_REGISTER;
744
745   case XED_REG_RBP:
746     *v3_reg = (addr_t)&(info->vm_regs.rbp);
747     *reg_len = 8;
748     return GPR_REGISTER;
749   case XED_REG_EBP:
750     *v3_reg = (addr_t)&(info->vm_regs.rbp);
751     *reg_len = 4;
752     return GPR_REGISTER;
753   case XED_REG_BP:
754     *v3_reg = (addr_t)&(info->vm_regs.rbp);
755     *reg_len = 2;
756     return GPR_REGISTER;
757   case XED_REG_BPL:
758     *v3_reg = (addr_t)&(info->vm_regs.rbp);
759     *reg_len = 1;
760     return GPR_REGISTER;
761
762
763
764   case XED_REG_RSI:
765     *v3_reg = (addr_t)&(info->vm_regs.rsi);
766     *reg_len = 8;
767     return GPR_REGISTER;
768   case XED_REG_ESI:
769     *v3_reg = (addr_t)&(info->vm_regs.rsi);
770     *reg_len = 4;
771     return GPR_REGISTER;
772   case XED_REG_SI:
773     *v3_reg = (addr_t)&(info->vm_regs.rsi);
774     *reg_len = 2;
775     return GPR_REGISTER;
776   case XED_REG_SIL:
777     *v3_reg = (addr_t)&(info->vm_regs.rsi);
778     *reg_len = 1;
779     return GPR_REGISTER;
780
781
782   case XED_REG_RDI:
783     *v3_reg = (addr_t)&(info->vm_regs.rdi);
784     *reg_len = 8;
785     return GPR_REGISTER;
786   case XED_REG_EDI:
787     *v3_reg = (addr_t)&(info->vm_regs.rdi);
788     *reg_len = 4;
789     return GPR_REGISTER;
790   case XED_REG_DI:
791     *v3_reg = (addr_t)&(info->vm_regs.rdi);
792     *reg_len = 2;
793     return GPR_REGISTER;
794   case XED_REG_DIL:
795     *v3_reg = (addr_t)&(info->vm_regs.rdi);
796     *reg_len = 1;
797     return GPR_REGISTER;
798
799
800
801
802
803   case XED_REG_R8:
804     *v3_reg = (addr_t)&(info->vm_regs.r8);
805     *reg_len = 8;
806     return GPR_REGISTER;
807   case XED_REG_R8D:
808     *v3_reg = (addr_t)&(info->vm_regs.r8);
809     *reg_len = 4;
810     return GPR_REGISTER;
811   case XED_REG_R8W:
812     *v3_reg = (addr_t)&(info->vm_regs.r8);
813     *reg_len = 2;
814     return GPR_REGISTER;
815   case XED_REG_R8B:
816     *v3_reg = (addr_t)&(info->vm_regs.r8);
817     *reg_len = 1;
818     return GPR_REGISTER;
819
820   case XED_REG_R9:
821     *v3_reg = (addr_t)&(info->vm_regs.r9);
822     *reg_len = 8;
823     return GPR_REGISTER;
824   case XED_REG_R9D:
825     *v3_reg = (addr_t)&(info->vm_regs.r9);
826     *reg_len = 4;
827     return GPR_REGISTER;
828   case XED_REG_R9W:
829     *v3_reg = (addr_t)&(info->vm_regs.r9);
830     *reg_len = 2;
831     return GPR_REGISTER;
832   case XED_REG_R9B:
833     *v3_reg = (addr_t)&(info->vm_regs.r9);
834     *reg_len = 1;
835     return GPR_REGISTER;
836
837   case XED_REG_R10:
838     *v3_reg = (addr_t)&(info->vm_regs.r10);
839     *reg_len = 8;
840     return GPR_REGISTER;
841   case XED_REG_R10D:
842     *v3_reg = (addr_t)&(info->vm_regs.r10);
843     *reg_len = 4;
844     return GPR_REGISTER;
845   case XED_REG_R10W:
846     *v3_reg = (addr_t)&(info->vm_regs.r10);
847     *reg_len = 2;
848     return GPR_REGISTER;
849   case XED_REG_R10B:
850     *v3_reg = (addr_t)&(info->vm_regs.r10);
851     *reg_len = 1;
852     return GPR_REGISTER;
853
854   case XED_REG_R11:
855     *v3_reg = (addr_t)&(info->vm_regs.r11);
856     *reg_len = 8;
857     return GPR_REGISTER;
858   case XED_REG_R11D:
859     *v3_reg = (addr_t)&(info->vm_regs.r11);
860     *reg_len = 4;
861     return GPR_REGISTER;
862   case XED_REG_R11W:
863     *v3_reg = (addr_t)&(info->vm_regs.r11);
864     *reg_len = 2;
865     return GPR_REGISTER;
866   case XED_REG_R11B:
867     *v3_reg = (addr_t)&(info->vm_regs.r11);
868     *reg_len = 1;
869     return GPR_REGISTER;
870
871   case XED_REG_R12:
872     *v3_reg = (addr_t)&(info->vm_regs.r12);
873     *reg_len = 8;
874     return GPR_REGISTER;
875   case XED_REG_R12D:
876     *v3_reg = (addr_t)&(info->vm_regs.r12);
877     *reg_len = 4;
878     return GPR_REGISTER;
879   case XED_REG_R12W:
880     *v3_reg = (addr_t)&(info->vm_regs.r12);
881     *reg_len = 2;
882     return GPR_REGISTER;
883   case XED_REG_R12B:
884     *v3_reg = (addr_t)&(info->vm_regs.r12);
885     *reg_len = 1;
886     return GPR_REGISTER;
887
888   case XED_REG_R13:
889     *v3_reg = (addr_t)&(info->vm_regs.r13);
890     *reg_len = 8;
891     return GPR_REGISTER;
892   case XED_REG_R13D:
893     *v3_reg = (addr_t)&(info->vm_regs.r13);
894     *reg_len = 4;
895     return GPR_REGISTER;
896   case XED_REG_R13W:
897     *v3_reg = (addr_t)&(info->vm_regs.r13);
898     *reg_len = 2;
899     return GPR_REGISTER;
900   case XED_REG_R13B:
901     *v3_reg = (addr_t)&(info->vm_regs.r13);
902     *reg_len = 1;
903     return GPR_REGISTER;
904
905   case XED_REG_R14:
906     *v3_reg = (addr_t)&(info->vm_regs.r14);
907     *reg_len = 8;
908     return GPR_REGISTER;
909   case XED_REG_R14D:
910     *v3_reg = (addr_t)&(info->vm_regs.r14);
911     *reg_len = 4;
912     return GPR_REGISTER;
913   case XED_REG_R14W:
914     *v3_reg = (addr_t)&(info->vm_regs.r14);
915     *reg_len = 2;
916     return GPR_REGISTER;
917   case XED_REG_R14B:
918     *v3_reg = (addr_t)&(info->vm_regs.r14);
919     *reg_len = 1;
920     return GPR_REGISTER;
921
922   case XED_REG_R15:
923     *v3_reg = (addr_t)&(info->vm_regs.r15);
924     *reg_len = 8;
925     return GPR_REGISTER;
926   case XED_REG_R15D:
927     *v3_reg = (addr_t)&(info->vm_regs.r15);
928     *reg_len = 4;
929     return GPR_REGISTER;
930   case XED_REG_R15W:
931     *v3_reg = (addr_t)&(info->vm_regs.r15);
932     *reg_len = 2;
933     return GPR_REGISTER;
934   case XED_REG_R15B:
935     *v3_reg = (addr_t)&(info->vm_regs.r15);
936     *reg_len = 1;
937     return GPR_REGISTER;
938
939
940     /* 
941      *  CTRL REGS
942      */
943   case XED_REG_RIP:
944     *v3_reg = (addr_t)&(info->rip);
945     *reg_len = 8;
946     return CTRL_REGISTER;
947   case XED_REG_EIP:
948     *v3_reg = (addr_t)&(info->rip);
949     *reg_len = 4;
950     return CTRL_REGISTER;  
951   case XED_REG_IP:
952     *v3_reg = (addr_t)&(info->rip);
953     *reg_len = 2;
954     return CTRL_REGISTER;
955
956   case XED_REG_FLAGS:
957     *v3_reg = (addr_t)&(info->ctrl_regs.rflags);
958     *reg_len = 2;
959     return CTRL_REGISTER;
960   case XED_REG_EFLAGS:
961     *v3_reg = (addr_t)&(info->ctrl_regs.rflags);
962     *reg_len = 4;
963     return CTRL_REGISTER;
964   case XED_REG_RFLAGS:
965     *v3_reg = (addr_t)&(info->ctrl_regs.rflags);
966     *reg_len = 8;
967     return CTRL_REGISTER;
968
969   case XED_REG_CR0:
970     *v3_reg = (addr_t)&(info->ctrl_regs.cr0);
971     *reg_len = 4;
972     return CTRL_REGISTER;
973   case XED_REG_CR2:
974     *v3_reg = (addr_t)&(info->ctrl_regs.cr2);
975     *reg_len = 4;
976     return CTRL_REGISTER;
977   case XED_REG_CR3:
978     *v3_reg = (addr_t)&(info->ctrl_regs.cr3);
979     *reg_len = 4;
980     return CTRL_REGISTER;
981   case XED_REG_CR4:
982     *v3_reg = (addr_t)&(info->ctrl_regs.cr4);
983    *reg_len = 4;
984     return CTRL_REGISTER;
985   case XED_REG_CR8:
986     *v3_reg = (addr_t)&(info->ctrl_regs.cr8);
987     *reg_len = 4;
988     return CTRL_REGISTER;
989
990   case XED_REG_CR1:
991   case XED_REG_CR5:
992   case XED_REG_CR6:
993   case XED_REG_CR7:
994   case XED_REG_CR9:
995   case XED_REG_CR10:
996   case XED_REG_CR11:
997   case XED_REG_CR12:
998   case XED_REG_CR13:
999   case XED_REG_CR14:
1000   case XED_REG_CR15:
1001     return -1;
1002
1003
1004
1005
1006     /* 
1007      * SEGMENT REGS
1008      */
1009   case XED_REG_CS:
1010     *v3_reg = (addr_t)&(info->segments.cs);
1011     return SEGMENT_REGISTER;
1012   case XED_REG_DS:
1013     *v3_reg = (addr_t)&(info->segments.ds);
1014     return SEGMENT_REGISTER;
1015   case XED_REG_ES:
1016     *v3_reg = (addr_t)&(info->segments.es);
1017     return SEGMENT_REGISTER;
1018   case XED_REG_SS:
1019     *v3_reg = (addr_t)&(info->segments.ss);
1020     return SEGMENT_REGISTER;
1021   case XED_REG_FS:
1022     *v3_reg = (addr_t)&(info->segments.fs);
1023     return SEGMENT_REGISTER;
1024   case XED_REG_GS:
1025     *v3_reg = (addr_t)&(info->segments.gs);
1026     return SEGMENT_REGISTER;
1027
1028
1029   case XED_REG_GDTR:
1030   case XED_REG_LDTR:
1031   case XED_REG_IDTR:
1032   case XED_REG_TR:
1033     PrintError("Segment selector operand... Don't know how to handle this...\n");
1034     return -1;
1035
1036     /* 
1037      *  DEBUG REGS
1038      */
1039   case XED_REG_DR0:
1040   case XED_REG_DR1:
1041   case XED_REG_DR2:
1042   case XED_REG_DR3:
1043   case XED_REG_DR4:
1044   case XED_REG_DR5:
1045   case XED_REG_DR6:
1046   case XED_REG_DR7:
1047   case XED_REG_DR8:
1048   case XED_REG_DR9:
1049   case XED_REG_DR10:
1050   case XED_REG_DR11:
1051   case XED_REG_DR12:
1052   case XED_REG_DR13:
1053   case XED_REG_DR14:
1054   case XED_REG_DR15:
1055     return -1;
1056
1057
1058
1059
1060
1061
1062   case XED_REG_XMM0:
1063   case XED_REG_XMM1:
1064   case XED_REG_XMM2:
1065   case XED_REG_XMM3:
1066   case XED_REG_XMM4:
1067   case XED_REG_XMM5:
1068   case XED_REG_XMM6:
1069   case XED_REG_XMM7:
1070   case XED_REG_XMM8:
1071   case XED_REG_XMM9:
1072   case XED_REG_XMM10:
1073   case XED_REG_XMM11:
1074   case XED_REG_XMM12:
1075   case XED_REG_XMM13:
1076   case XED_REG_XMM14:
1077   case XED_REG_XMM15:
1078
1079   case XED_REG_MMX0:
1080   case XED_REG_MMX1:
1081   case XED_REG_MMX2:
1082   case XED_REG_MMX3:
1083   case XED_REG_MMX4:
1084   case XED_REG_MMX5:
1085   case XED_REG_MMX6:
1086   case XED_REG_MMX7:
1087
1088   case XED_REG_ST0:
1089   case XED_REG_ST1:
1090   case XED_REG_ST2:
1091   case XED_REG_ST3:
1092   case XED_REG_ST4:
1093   case XED_REG_ST5:
1094   case XED_REG_ST6:
1095   case XED_REG_ST7:
1096
1097   case XED_REG_ONE:
1098   case XED_REG_STACKPUSH:
1099   case XED_REG_STACKPOP:
1100     
1101   case XED_REG_TSC:
1102   case XED_REG_TSCAUX:
1103   case XED_REG_MSRS:
1104
1105   case XED_REG_X87CONTROL:
1106   case XED_REG_X87STATUS:
1107   case XED_REG_X87TOP:
1108   case XED_REG_X87TAG:
1109   case XED_REG_X87PUSH:
1110   case XED_REG_X87POP:
1111   case XED_REG_X87POP2:
1112
1113   case XED_REG_MXCSR:
1114
1115   case XED_REG_TMP0:
1116   case XED_REG_TMP1:
1117   case XED_REG_TMP2:
1118   case XED_REG_TMP3:
1119   case XED_REG_TMP4:
1120   case XED_REG_TMP5:
1121   case XED_REG_TMP6:
1122   case XED_REG_TMP7:
1123   case XED_REG_TMP8:
1124   case XED_REG_TMP9:
1125   case XED_REG_TMP10:
1126   case XED_REG_TMP11:
1127   case XED_REG_TMP12:
1128   case XED_REG_TMP13:
1129   case XED_REG_TMP14:
1130   case XED_REG_TMP15:
1131
1132   case XED_REG_LAST:
1133
1134   case XED_REG_ERROR:
1135     // error??
1136     return -1;
1137
1138   }
1139
1140
1141   return 0;
1142 }
1143
1144
1145
1146 static v3_op_type_t get_opcode(xed_iform_enum_t iform) {
1147
1148   switch (iform) {
1149
1150     /* Control Instructions */
1151
1152   case XED_IFORM_MOV_CR_GPR64_CR:
1153   case XED_IFORM_MOV_CR_GPR32_CR:
1154     return V3_OP_MOVCR2;
1155
1156   case XED_IFORM_MOV_CR_CR_GPR64:
1157   case XED_IFORM_MOV_CR_CR_GPR32:
1158     return V3_OP_MOV2CR;
1159
1160   case XED_IFORM_SMSW_GPRv:
1161     return V3_OP_SMSW;
1162
1163   case XED_IFORM_LMSW_GPR16:
1164     return V3_OP_LMSW;
1165
1166   case XED_IFORM_CLTS:
1167     return V3_OP_CLTS;
1168
1169   case XED_IFORM_INVLPG_MEMb:
1170     return V3_OP_INVLPG;
1171
1172
1173     /* Data Instructions */
1174
1175     // Write
1176   case XED_IFORM_ADC_MEMv_GPRv:
1177   case XED_IFORM_ADC_MEMv_IMM:
1178   case XED_IFORM_ADC_MEMb_GPR8:
1179   case XED_IFORM_ADC_MEMb_IMM:
1180     // Read
1181   case XED_IFORM_ADC_GPRv_MEMv:
1182   case XED_IFORM_ADC_GPR8_MEMb:
1183     return V3_OP_ADC;
1184
1185     // Write
1186   case XED_IFORM_ADD_MEMv_GPRv:
1187   case XED_IFORM_ADD_MEMb_IMM:
1188   case XED_IFORM_ADD_MEMb_GPR8:
1189   case XED_IFORM_ADD_MEMv_IMM:
1190     // Read
1191   case XED_IFORM_ADD_GPRv_MEMv:
1192   case XED_IFORM_ADD_GPR8_MEMb:
1193     return V3_OP_ADD;
1194
1195     // Write
1196   case XED_IFORM_AND_MEMv_IMM:
1197   case XED_IFORM_AND_MEMb_GPR8:
1198   case XED_IFORM_AND_MEMv_GPRv:
1199   case XED_IFORM_AND_MEMb_IMM:
1200     // Read
1201   case XED_IFORM_AND_GPR8_MEMb:
1202   case XED_IFORM_AND_GPRv_MEMv:
1203     return V3_OP_AND;
1204
1205     // Write
1206   case XED_IFORM_SUB_MEMv_IMM:
1207   case XED_IFORM_SUB_MEMb_GPR8:
1208   case XED_IFORM_SUB_MEMb_IMM:
1209   case XED_IFORM_SUB_MEMv_GPRv:
1210     // Read
1211   case XED_IFORM_SUB_GPR8_MEMb:
1212   case XED_IFORM_SUB_GPRv_MEMv:
1213     return V3_OP_SUB;
1214
1215     // Write
1216   case XED_IFORM_MOV_MEMv_GPRv:
1217   case XED_IFORM_MOV_MEMb_GPR8:
1218   case XED_IFORM_MOV_MEMb_AL:
1219   case XED_IFORM_MOV_MEMv_IMM:
1220   case XED_IFORM_MOV_MEMb_IMM:
1221     // Read 
1222   case XED_IFORM_MOV_GPRv_MEMv:
1223   case XED_IFORM_MOV_GPR8_MEMb:
1224   case XED_IFORM_MOV_AL_MEMb:
1225     return V3_OP_MOV;
1226
1227
1228     // Read 
1229   case XED_IFORM_MOVZX_GPRv_MEMb:
1230   case XED_IFORM_MOVZX_GPRv_MEMw:
1231     return V3_OP_MOVZX;
1232
1233     // Read 
1234   case XED_IFORM_MOVSX_GPRv_MEMb:
1235   case XED_IFORM_MOVSX_GPRv_MEMw:
1236     return V3_OP_MOVSX;
1237
1238
1239   case XED_IFORM_DEC_MEMv:
1240   case XED_IFORM_DEC_MEMb:
1241     return V3_OP_DEC;
1242
1243   case XED_IFORM_INC_MEMb:
1244   case XED_IFORM_INC_MEMv:
1245     return V3_OP_INC;
1246
1247     // Write
1248   case XED_IFORM_OR_MEMv_IMM:
1249   case XED_IFORM_OR_MEMb_IMM:
1250   case XED_IFORM_OR_MEMv_GPRv:
1251   case XED_IFORM_OR_MEMb_GPR8:
1252     // Read
1253   case XED_IFORM_OR_GPRv_MEMv:
1254   case XED_IFORM_OR_GPR8_MEMb:
1255     return V3_OP_OR;
1256
1257     // Write
1258   case XED_IFORM_XOR_MEMv_GPRv:
1259   case XED_IFORM_XOR_MEMb_IMM:
1260   case XED_IFORM_XOR_MEMb_GPR8:
1261   case XED_IFORM_XOR_MEMv_IMM:
1262     // Read
1263   case XED_IFORM_XOR_GPRv_MEMv:
1264   case XED_IFORM_XOR_GPR8_MEMb:
1265     return V3_OP_XOR;
1266
1267   case XED_IFORM_NEG_MEMb:
1268   case XED_IFORM_NEG_MEMv:
1269     return V3_OP_NEG;
1270
1271   case XED_IFORM_NOT_MEMv:
1272   case XED_IFORM_NOT_MEMb:
1273     return V3_OP_NOT;
1274
1275   case XED_IFORM_XCHG_MEMv_GPRv:
1276   case XED_IFORM_XCHG_MEMb_GPR8:
1277     return V3_OP_XCHG;
1278
1279   case XED_IFORM_SETB_MEMb:
1280     return V3_OP_SETB;
1281
1282   case XED_IFORM_SETBE_MEMb:
1283     return V3_OP_SETBE;
1284
1285   case XED_IFORM_SETL_MEMb:
1286     return V3_OP_SETL;
1287
1288   case XED_IFORM_SETLE_MEMb:
1289     return V3_OP_SETLE;
1290
1291   case XED_IFORM_SETNB_MEMb:
1292     return V3_OP_SETNB;
1293
1294   case XED_IFORM_SETNBE_MEMb:
1295     return V3_OP_SETNBE;
1296
1297   case XED_IFORM_SETNL_MEMb:
1298     return V3_OP_SETNL;
1299
1300   case XED_IFORM_SETNLE_MEMb:
1301     return V3_OP_SETNLE;
1302
1303   case XED_IFORM_SETNO_MEMb:
1304     return V3_OP_SETNO;
1305     
1306   case XED_IFORM_SETNP_MEMb:
1307     return V3_OP_SETNP;
1308
1309   case XED_IFORM_SETNS_MEMb:
1310     return V3_OP_SETNS;
1311
1312   case XED_IFORM_SETNZ_MEMb:
1313     return V3_OP_SETNZ;
1314
1315   case XED_IFORM_SETO_MEMb:
1316     return V3_OP_SETO;
1317     
1318   case XED_IFORM_SETP_MEMb:
1319     return V3_OP_SETP;
1320
1321   case XED_IFORM_SETS_MEMb:
1322     return V3_OP_SETS;
1323
1324   case XED_IFORM_SETZ_MEMb:
1325     return V3_OP_SETZ;
1326
1327
1328   case XED_IFORM_MOVSB:
1329   case XED_IFORM_MOVSW:
1330   case XED_IFORM_MOVSD:
1331   case XED_IFORM_MOVSQ:
1332     return V3_OP_MOVS;
1333
1334   default:
1335     return V3_INVALID_OP;
1336   }
1337 }