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.


added copyright tags
[palacios.git] / palacios / src / palacios / vmm_xed.c
1 /* Northwestern University */
2 /* (c) 2008, Jack Lange <jarusl@cs.northwestern.edu> */
3
4 #ifdef __DECODER_TEST__
5 #include "vmm_decoder.h"
6 #include "vmm_xed.h"
7 #include <xed/xed-interface.h>
8 #include "vm_guest.h"
9 #include "test.h"
10 #else
11 #include <palacios/vmm_decoder.h>
12 #include <palacios/vmm_xed.h>
13 #include <xed/xed-interface.h>
14 #include <palacios/vm_guest.h>
15 #include <palacios/vmm.h>
16
17
18 #endif
19
20 static xed_state_t decoder_state;
21
22 #define GPR_REGISTER     0
23 #define SEGMENT_REGISTER 1
24 #define CTRL_REGISTER    2
25 #define DEBUG_REGISTER   3
26
27
28
29 /* Disgusting mask hack...
30    I can't think right now, so we'll do it this way...
31 */
32 static const ullong_t mask_1 = 0x00000000000000ffLL;
33 static const ullong_t mask_2 = 0x000000000000ffffLL;
34 static const ullong_t mask_4 = 0x00000000ffffffffLL;
35 static const ullong_t mask_8 = 0xffffffffffffffffLL;
36
37
38 #define MASK(val, length) ({                    \
39       ullong_t mask = 0x0LL;                    \
40       switch (length) {                         \
41       case 1:                                   \
42         mask = mask_1;                          \
43       case 2:                                   \
44         mask = mask_2;                          \
45       case 4:                                   \
46         mask = mask_4;                          \
47       case 8:                                   \
48         mask = mask_8;                          \
49       }                                         \
50       val & mask;})                             \
51
52 struct memory_operand {
53   uint_t segment_size;
54   addr_t segment;
55   uint_t base_size;
56   addr_t base;
57   uint_t index_size;
58   addr_t index;
59   addr_t scale;
60   uint_t displacement_size;
61   ullong_t displacement;
62 };
63
64
65
66 // This returns a pointer to a V3_OPCODE_[*] array defined in vmm_decoder.h
67 static int get_opcode(xed_iform_enum_t iform, addr_t * opcode);
68
69 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);
70 static int get_memory_operand(struct guest_info * info,  xed_decoded_inst_t * xed_instr, uint_t index, struct x86_operand * operand);
71
72 static int set_decoder_mode(struct guest_info * info, xed_state_t * state) {
73   switch (info->cpu_mode) {
74   case REAL:
75     if (state->mmode != XED_MACHINE_MODE_LEGACY_16) {
76       xed_state_init(state,
77                      XED_MACHINE_MODE_LEGACY_16, 
78                      XED_ADDRESS_WIDTH_16b, 
79                      XED_ADDRESS_WIDTH_16b); 
80     }
81    break;
82   case PROTECTED:
83   case PROTECTED_PAE:
84     if (state->mmode != XED_MACHINE_MODE_LEGACY_32) {
85       xed_state_init(state,
86                      XED_MACHINE_MODE_LEGACY_32, 
87                      XED_ADDRESS_WIDTH_32b, 
88                      XED_ADDRESS_WIDTH_32b);
89     }
90     break;
91   case LONG:
92     if (state->mmode != XED_MACHINE_MODE_LONG_64) {    
93       state->mmode = XED_MACHINE_MODE_LONG_64;
94     }
95     break;
96   default:
97     return -1;
98   }
99   return 0;
100 }
101
102 int is_flags_reg(xed_reg_enum_t xed_reg) {
103   switch (xed_reg) {
104   case XED_REG_FLAGS:
105   case XED_REG_EFLAGS:
106   case XED_REG_RFLAGS:
107     return 1;
108   default:
109     return 0;
110   }
111 }
112
113
114
115 int init_decoder() {
116   xed_tables_init();
117   xed_state_zero(&decoder_state);
118   return 0;
119 }
120
121
122
123 int v3_basic_mem_decode(struct guest_info * info, addr_t instr_ptr, struct basic_instr_info * instr_info) {
124   xed_decoded_inst_t xed_instr;
125   xed_error_enum_t xed_error;
126   
127
128   if (set_decoder_mode(info, &decoder_state) == -1) {
129     PrintError("Could not set decoder mode\n");
130     return -1;
131   }
132
133
134   xed_decoded_inst_zero_set_mode(&xed_instr, &decoder_state);
135
136   xed_error = xed_decode(&xed_instr, 
137                          REINTERPRET_CAST(const xed_uint8_t *, instr_ptr), 
138                          XED_MAX_INSTRUCTION_BYTES);
139
140   if (xed_error != XED_ERROR_NONE) {
141     PrintError("Xed error: %s\n", xed_error_enum_t2str(xed_error));
142     return -1;
143   }
144
145   instr_info->instr_length = xed_decoded_inst_get_length(&xed_instr);
146
147
148  if (xed_decoded_inst_number_of_memory_operands(&xed_instr) == 0) {
149    PrintError("Tried to decode memory operation with no memory operands\n");
150    return -1;
151  }
152
153  instr_info->op_size = xed_decoded_inst_get_memory_operand_length(&xed_instr, 0);
154
155
156  xed_category_enum_t cat = xed_decoded_inst_get_category(&xed_instr);
157  if (cat == XED_CATEGORY_STRINGOP) {
158    instr_info->str_op = 1;
159  } else {
160    instr_info->str_op = 0;
161  }
162
163  xed_operand_values_t * operands = xed_decoded_inst_operands(&xed_instr);
164  if (xed_operand_values_has_real_rep(operands)) {
165    instr_info->has_rep = 1;
166  } else {
167    instr_info->has_rep = 0;
168  }
169
170  return 0;
171 }
172
173
174
175 int v3_decode(struct guest_info * info, addr_t instr_ptr, struct x86_instr * instr) {
176   xed_decoded_inst_t xed_instr;
177   xed_error_enum_t xed_error;
178
179
180
181   if (set_decoder_mode(info, &decoder_state) == -1) {
182     PrintError("Could not set decoder mode\n");
183     return -1;
184   }
185
186
187
188   xed_decoded_inst_zero_set_mode(&xed_instr, &decoder_state);
189
190   xed_error = xed_decode(&xed_instr, 
191                          REINTERPRET_CAST(const xed_uint8_t *, instr_ptr), 
192                          XED_MAX_INSTRUCTION_BYTES);
193
194
195   if (xed_error != XED_ERROR_NONE) {
196     PrintError("Xed error: %s\n", xed_error_enum_t2str(xed_error));
197     return -1;
198   }
199
200   const xed_inst_t * xi = xed_decoded_inst_inst(&xed_instr);
201   
202   instr->instr_length = xed_decoded_inst_get_length(&xed_instr);
203   instr->num_operands = xed_decoded_inst_noperands(&xed_instr);
204
205   xed_iform_enum_t iform = xed_decoded_inst_get_iform_enum(&xed_instr);
206
207
208   PrintDebug("iform=%s\n", xed_iform_enum_t2str(iform));
209
210
211   if (instr->num_operands > 3) {
212     PrintDebug("Special Case Not Handled\n");
213     return -1;
214     // special case
215   } else if (instr->num_operands == 3) {
216     const xed_operand_t * op = xed_inst_operand(xi, 2);
217     xed_operand_enum_t op_enum = xed_operand_name(op);
218
219     if ((!xed_operand_is_register(op_enum)) ||
220         (!is_flags_reg(xed_decoded_inst_get_reg(&xed_instr, op_enum)))) {
221       // special case
222       PrintDebug("Special Case not handled\n");
223       return -1;
224     }
225   }
226
227
228
229
230
231   if (get_opcode(iform, &(instr->opcode)) == -1) {
232     PrintDebug("Could not get opcode. (iform=%s)\n", xed_iform_enum_t2str(iform));
233     return -1;
234   }
235
236
237
238
239   //PrintDebug("Number of operands: %d\n", instr->num_operands);
240   //PrintDebug("INSTR length: %d\n", instr->instr_length);
241
242   // set first operand
243   if (instr->num_operands >= 1) {
244     const xed_operand_t * op = xed_inst_operand(xi, 0);
245     xed_operand_enum_t op_enum = xed_operand_name(op);
246
247     struct x86_operand * v3_op = NULL;
248
249     if (xed_operand_written(op)) {
250       v3_op = &(instr->dst_operand);
251     } else {
252       v3_op = &(instr->src_operand);
253     }
254
255
256     if (xed_operand_is_register(op_enum)) {
257       xed_reg_enum_t xed_reg =  xed_decoded_inst_get_reg(&xed_instr, op_enum);
258       int v3_reg_type = xed_reg_to_v3_reg(info, 
259                                           xed_reg, 
260                                           &(v3_op->operand), 
261                                           &(v3_op->size));
262                                           
263       if (v3_reg_type == -1) {
264         PrintError("First operand is an Unhandled Operand: %s\n", xed_reg_enum_t2str(xed_reg));
265         v3_op->type = INVALID_OPERAND;
266         return -1;
267       } else if (v3_reg_type == SEGMENT_REGISTER) {
268         struct v3_segment * seg_reg = (struct v3_segment *)(v3_op->operand);
269         v3_op->operand = (addr_t)&(seg_reg->selector);
270       }
271
272       v3_op->type = REG_OPERAND;
273     } else {
274
275       switch (op_enum) {
276
277       case XED_OPERAND_MEM0:
278         {
279           /*
280             struct x86_operand * operand = &(instr->dst_operand);
281             
282             if (xed_decoded_inst_mem_read(&xed_instr, 0)) {
283             operand = &(instr->src_operand);
284             } else if (xed_decoded_inst_mem_written(&xed_instr, 0)) {
285             operand = &(instr->dst_operand);
286             }
287           */
288           
289           if (get_memory_operand(info, &xed_instr, 0, v3_op) == -1) {
290             PrintError("Could not get first memory operand\n");
291             return -1;
292           }
293         }
294         break;
295
296       case XED_OPERAND_MEM1:
297       case XED_OPERAND_IMM1:
298         // illegal
299         PrintError("Illegal Operand Order\n");
300         return -1;
301
302
303       case XED_OPERAND_IMM0:
304       case XED_OPERAND_AGEN:
305       case XED_OPERAND_PTR:
306       case XED_OPERAND_RELBR:
307       default:
308         PrintError("Unhandled Operand Type\n");
309         return -1;
310
311
312       }
313     }
314   }
315
316   // set second operand
317   if (instr->num_operands >= 2) {
318     const xed_operand_t * op = xed_inst_operand(xi, 1);
319     //   xed_operand_type_enum_t op_type = xed_operand_type(op);
320     xed_operand_enum_t op_enum = xed_operand_name(op);
321     
322     struct x86_operand * v3_op;
323
324     if (xed_operand_written(op)) {
325       v3_op = &(instr->dst_operand);
326     } else {
327       v3_op = &(instr->src_operand);
328     }
329
330
331     if (xed_operand_is_register(op_enum)) {
332       xed_reg_enum_t xed_reg =  xed_decoded_inst_get_reg(&xed_instr, op_enum);
333       int v3_reg_type = xed_reg_to_v3_reg(info, 
334                                           xed_reg, 
335                                           &(v3_op->operand), 
336                                           &(v3_op->size));
337       if (v3_reg_type == -1) {
338         PrintError("Second operand is an Unhandled Operand: %s\n", xed_reg_enum_t2str(xed_reg));
339         v3_op->type = INVALID_OPERAND;
340         return -1;
341       } else if (v3_reg_type == SEGMENT_REGISTER) {
342         struct v3_segment * seg_reg = (struct v3_segment *)(v3_op->operand);
343         v3_op->operand = (addr_t)&(seg_reg->selector);
344       }
345
346       v3_op->type = REG_OPERAND;
347     
348
349     } else {
350
351       switch (op_enum) {
352
353       case XED_OPERAND_MEM0:
354         {
355
356           /*
357           if (xed_decoded_inst_mem_read(&xed_instr, 0)) {
358             v3_op = &(instr->src_operand);
359           } else if (xed_decoded_inst_mem_written(&xed_instr, 0)) {
360             v3_op = &(instr->dst_operand);
361           }
362           */
363
364           if (get_memory_operand(info, &xed_instr, 0, v3_op) == -1) {
365             PrintError("Could not get first memory operand\n");
366             return -1;
367           }
368         }
369         break;
370
371       case XED_OPERAND_IMM0:
372         {
373           instr->src_operand.size = xed_decoded_inst_get_immediate_width(&xed_instr);
374
375           if (instr->src_operand.size > 4) {
376             PrintError("Unhandled 64 bit immediates\n");
377             return -1;
378           }
379           instr->src_operand.operand = xed_decoded_inst_get_unsigned_immediate(&xed_instr);
380
381           instr->src_operand.type = IMM_OPERAND;
382
383         }
384         break;
385
386       case XED_OPERAND_MEM1:
387       case XED_OPERAND_IMM1:
388         // illegal
389         PrintError("Illegal Operand Order\n");
390         return -1;
391         
392       case XED_OPERAND_AGEN:
393       case XED_OPERAND_PTR:
394       case XED_OPERAND_RELBR:
395       default:
396         PrintError("Unhandled Operand Type\n");
397         return -1;
398       }
399     }
400
401   }
402
403   // set third operand
404   if (instr->num_operands >= 3) {
405     const xed_operand_t * op = xed_inst_operand(xi, 2);
406     //  xed_operand_type_enum_t op_type = xed_operand_type(op);
407     xed_operand_enum_t op_enum = xed_operand_name(op);
408
409     if (xed_operand_is_register(op_enum)) {
410       xed_reg_enum_t xed_reg =  xed_decoded_inst_get_reg(&xed_instr, op_enum);
411       int v3_reg_type = xed_reg_to_v3_reg(info, 
412                                           xed_reg, 
413                                           &(instr->third_operand.operand), 
414                                           &(instr->third_operand.size));
415
416       if (v3_reg_type == -1) {
417         PrintError("Third operand is an Unhandled Operand: %s\n", xed_reg_enum_t2str(xed_reg));
418         instr->third_operand.type = INVALID_OPERAND;
419         return -1;
420       } else if (v3_reg_type == SEGMENT_REGISTER) {
421         struct v3_segment * seg_reg = (struct v3_segment *)(instr->third_operand.operand);
422         instr->third_operand.operand = (addr_t)&(seg_reg->selector);
423       }
424
425
426       instr->third_operand.type = REG_OPERAND;
427
428
429     } else {
430       //      PrintError("Unhandled third operand type %s\n", xed_operand_type_enum_t2str(op_type));
431       return -1;
432     }
433
434
435   }
436
437
438
439     return 0;
440 }
441
442
443 int v3_encode(struct guest_info * info, struct x86_instr * instr, char * instr_buf) {
444
445   return -1;
446 }
447
448
449
450
451
452 static int get_memory_operand(struct guest_info * info,  xed_decoded_inst_t * xed_instr, uint_t op_index, struct x86_operand * operand) {
453   struct memory_operand mem_op;
454
455   addr_t seg;
456   addr_t base;
457   addr_t scale;
458   addr_t index;
459   ullong_t displacement;
460   // struct v3_segment * seg_reg;
461
462
463
464
465   memset((void*)&mem_op, '\0', sizeof(struct memory_operand));
466
467   xed_reg_enum_t xed_seg = xed_decoded_inst_get_seg_reg(xed_instr, op_index);
468   if (xed_seg != XED_REG_INVALID) {
469     struct v3_segment *tmp_segment;
470     if (xed_reg_to_v3_reg(info, xed_seg, (addr_t *)&tmp_segment, &(mem_op.segment_size)) == -1) {
471       PrintError("Unhandled Segment Register\n");
472       return -1;
473     }
474     mem_op.segment = tmp_segment->base;
475   }
476
477   xed_reg_enum_t xed_base = xed_decoded_inst_get_base_reg(xed_instr, op_index);
478   if (xed_base != XED_REG_INVALID) {
479     addr_t base_reg;
480     if (xed_reg_to_v3_reg(info, xed_base, &base_reg, &(mem_op.base_size)) == -1) {
481       PrintError("Unhandled Base register\n");
482       return -1;
483     }
484     mem_op.base = *(addr_t *)base_reg;
485   }
486
487   
488
489   xed_reg_enum_t xed_idx = xed_decoded_inst_get_index_reg(xed_instr, op_index);
490   if ((op_index == 0) && (xed_idx != XED_REG_INVALID)) {
491     addr_t index_reg;
492     
493     if (xed_reg_to_v3_reg(info, xed_idx, &index_reg, &(mem_op.index_size)) == -1) {
494       PrintError("Unhandled Index Register\n");
495       return -1;
496     }
497
498     mem_op.index= *(addr_t *)index_reg;
499
500     xed_uint_t xed_scale = xed_decoded_inst_get_scale(xed_instr, op_index);
501     if (xed_scale != 0) {
502       mem_op.scale = xed_scale;
503     }
504   }
505
506
507   xed_uint_t disp_bits = xed_decoded_inst_get_memory_displacement_width(xed_instr, op_index);
508   if (disp_bits) {
509     xed_int64_t xed_disp = xed_decoded_inst_get_memory_displacement(xed_instr, op_index);
510
511     mem_op.displacement_size = disp_bits / 8;
512     mem_op.displacement = xed_disp;
513     
514   }
515
516   operand->type = MEM_OPERAND;
517   operand->size = xed_decoded_inst_get_memory_operand_length(xed_instr, op_index);
518   
519   
520
521   PrintDebug("Struct: Seg=%x, base=%x, index=%x, scale=%x, displacement=%x\n", 
522              mem_op.segment, mem_op.base, mem_op.index, mem_op.scale, mem_op.displacement);
523
524
525   seg = mem_op.segment;
526   base = MASK(mem_op.base, mem_op.base_size);
527   index = MASK(mem_op.index, mem_op.index_size);
528   scale = mem_op.scale;
529   displacement = MASK(mem_op.displacement, mem_op.displacement_size);
530
531   PrintDebug("Seg=%x, base=%x, index=%x, scale=%x, displacement=%x\n", seg, base, index, scale, displacement);
532   
533   operand->operand = seg + base + (scale * index) + displacement;
534   return 0;
535 }
536
537
538 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) {
539
540   switch (xed_reg) {
541   case XED_REG_INVALID:
542     *v3_reg = 0;
543     *reg_len = 0;
544     return -1;
545
546     /* 
547      * GPRs
548      */
549   case XED_REG_RAX: 
550     *v3_reg = (addr_t)&(info->vm_regs.rax);
551     *reg_len = 8;
552     return GPR_REGISTER;
553   case XED_REG_EAX:
554     *v3_reg = (addr_t)&(info->vm_regs.rax);
555     *reg_len = 4;
556     return GPR_REGISTER;
557   case XED_REG_AX:
558     *v3_reg = (addr_t)&(info->vm_regs.rax);
559     *reg_len = 2;
560     return GPR_REGISTER;
561   case XED_REG_AH:
562     *v3_reg = (addr_t)(&(info->vm_regs.rax)) + 1;
563     *reg_len = 1;
564     return GPR_REGISTER;
565   case XED_REG_AL:
566     *v3_reg = (addr_t)&(info->vm_regs.rax);
567     *reg_len = 1;
568     return GPR_REGISTER;
569
570   case XED_REG_RCX: 
571     *v3_reg = (addr_t)&(info->vm_regs.rcx);
572     *reg_len = 8;
573     return GPR_REGISTER;
574   case XED_REG_ECX:
575     *v3_reg = (addr_t)&(info->vm_regs.rcx);
576     *reg_len = 4;
577     return GPR_REGISTER;
578   case XED_REG_CX:
579     *v3_reg = (addr_t)&(info->vm_regs.rcx);
580     *reg_len = 2;
581     return GPR_REGISTER;
582   case XED_REG_CH:
583     *v3_reg = (addr_t)(&(info->vm_regs.rcx)) + 1;
584     *reg_len = 1;
585     return GPR_REGISTER;
586   case XED_REG_CL:
587     *v3_reg = (addr_t)&(info->vm_regs.rcx);
588     *reg_len = 1;
589     return GPR_REGISTER;
590
591   case XED_REG_RDX: 
592     *v3_reg = (addr_t)&(info->vm_regs.rdx);
593     *reg_len = 8;
594     return GPR_REGISTER;
595   case XED_REG_EDX:
596     *v3_reg = (addr_t)&(info->vm_regs.rdx);
597     *reg_len = 4;
598     return GPR_REGISTER;
599   case XED_REG_DX:
600     *v3_reg = (addr_t)&(info->vm_regs.rdx);
601     *reg_len = 2;
602     return GPR_REGISTER;
603   case XED_REG_DH:
604     *v3_reg = (addr_t)(&(info->vm_regs.rdx)) + 1;
605     *reg_len = 1;
606     return GPR_REGISTER;
607   case XED_REG_DL:
608     *v3_reg = (addr_t)&(info->vm_regs.rdx);
609     *reg_len = 1;
610     return GPR_REGISTER;
611
612   case XED_REG_RBX: 
613     *v3_reg = (addr_t)&(info->vm_regs.rbx);
614     *reg_len = 8;
615     return GPR_REGISTER;
616   case XED_REG_EBX:
617     *v3_reg = (addr_t)&(info->vm_regs.rbx);
618     *reg_len = 4;
619     return GPR_REGISTER;
620   case XED_REG_BX:
621     *v3_reg = (addr_t)&(info->vm_regs.rbx);
622     *reg_len = 2;
623     return GPR_REGISTER;
624   case XED_REG_BH:
625     *v3_reg = (addr_t)(&(info->vm_regs.rbx)) + 1;
626     *reg_len = 1;
627     return GPR_REGISTER;
628   case XED_REG_BL:
629     *v3_reg = (addr_t)&(info->vm_regs.rbx);
630     *reg_len = 1;
631     return GPR_REGISTER;
632
633
634   case XED_REG_RSP:
635     *v3_reg = (addr_t)&(info->vm_regs.rsp);
636     *reg_len = 8;
637     return GPR_REGISTER;
638   case XED_REG_ESP:
639     *v3_reg = (addr_t)&(info->vm_regs.rsp);
640     *reg_len = 4;
641     return GPR_REGISTER;
642   case XED_REG_SP:
643     *v3_reg = (addr_t)&(info->vm_regs.rsp);
644     *reg_len = 2;
645     return GPR_REGISTER;
646   case XED_REG_SPL:
647     *v3_reg = (addr_t)&(info->vm_regs.rsp);
648     *reg_len = 1;
649     return GPR_REGISTER;
650
651   case XED_REG_RBP:
652     *v3_reg = (addr_t)&(info->vm_regs.rbp);
653     *reg_len = 8;
654     return GPR_REGISTER;
655   case XED_REG_EBP:
656     *v3_reg = (addr_t)&(info->vm_regs.rbp);
657     *reg_len = 4;
658     return GPR_REGISTER;
659   case XED_REG_BP:
660     *v3_reg = (addr_t)&(info->vm_regs.rbp);
661     *reg_len = 2;
662     return GPR_REGISTER;
663   case XED_REG_BPL:
664     *v3_reg = (addr_t)&(info->vm_regs.rbp);
665     *reg_len = 1;
666     return GPR_REGISTER;
667
668
669
670   case XED_REG_RSI:
671     *v3_reg = (addr_t)&(info->vm_regs.rsi);
672     *reg_len = 8;
673     return GPR_REGISTER;
674   case XED_REG_ESI:
675     *v3_reg = (addr_t)&(info->vm_regs.rsi);
676     *reg_len = 4;
677     return GPR_REGISTER;
678   case XED_REG_SI:
679     *v3_reg = (addr_t)&(info->vm_regs.rsi);
680     *reg_len = 2;
681     return GPR_REGISTER;
682   case XED_REG_SIL:
683     *v3_reg = (addr_t)&(info->vm_regs.rsi);
684     *reg_len = 1;
685     return GPR_REGISTER;
686
687
688   case XED_REG_RDI:
689     *v3_reg = (addr_t)&(info->vm_regs.rdi);
690     *reg_len = 8;
691     return GPR_REGISTER;
692   case XED_REG_EDI:
693     *v3_reg = (addr_t)&(info->vm_regs.rdi);
694     *reg_len = 4;
695     return GPR_REGISTER;
696   case XED_REG_DI:
697     *v3_reg = (addr_t)&(info->vm_regs.rdi);
698     *reg_len = 2;
699     return GPR_REGISTER;
700   case XED_REG_DIL:
701     *v3_reg = (addr_t)&(info->vm_regs.rdi);
702     *reg_len = 1;
703     return GPR_REGISTER;
704
705
706     /* 
707      *  CTRL REGS
708      */
709   case XED_REG_RIP:
710     *v3_reg = (addr_t)&(info->rip);
711     *reg_len = 8;
712     return CTRL_REGISTER;
713   case XED_REG_EIP:
714     *v3_reg = (addr_t)&(info->rip);
715     *reg_len = 4;
716     return CTRL_REGISTER;  
717   case XED_REG_IP:
718     *v3_reg = (addr_t)&(info->rip);
719     *reg_len = 2;
720     return CTRL_REGISTER;
721
722   case XED_REG_FLAGS:
723     *v3_reg = (addr_t)&(info->ctrl_regs.rflags);
724     *reg_len = 2;
725     return CTRL_REGISTER;
726   case XED_REG_EFLAGS:
727     *v3_reg = (addr_t)&(info->ctrl_regs.rflags);
728     *reg_len = 4;
729     return CTRL_REGISTER;
730   case XED_REG_RFLAGS:
731     *v3_reg = (addr_t)&(info->ctrl_regs.rflags);
732     *reg_len = 8;
733     return CTRL_REGISTER;
734
735   case XED_REG_CR0:
736     *v3_reg = (addr_t)&(info->ctrl_regs.cr0);
737     *reg_len = 4;
738     return CTRL_REGISTER;
739   case XED_REG_CR2:
740     *v3_reg = (addr_t)&(info->ctrl_regs.cr2);
741     *reg_len = 4;
742     return CTRL_REGISTER;
743   case XED_REG_CR3:
744     *v3_reg = (addr_t)&(info->ctrl_regs.cr3);
745     *reg_len = 4;
746     return CTRL_REGISTER;
747   case XED_REG_CR4:
748     *v3_reg = (addr_t)&(info->ctrl_regs.cr4);
749     *reg_len = 4;
750     return CTRL_REGISTER;
751   case XED_REG_CR8:
752     *v3_reg = (addr_t)&(info->ctrl_regs.cr8);
753     *reg_len = 4;
754     return CTRL_REGISTER;
755
756   case XED_REG_CR1:
757   case XED_REG_CR5:
758   case XED_REG_CR6:
759   case XED_REG_CR7:
760   case XED_REG_CR9:
761   case XED_REG_CR10:
762   case XED_REG_CR11:
763   case XED_REG_CR12:
764   case XED_REG_CR13:
765   case XED_REG_CR14:
766   case XED_REG_CR15:
767     return -1;
768
769
770
771
772     /* 
773      * SEGMENT REGS
774      */
775   case XED_REG_CS:
776     *v3_reg = (addr_t)&(info->segments.cs);
777     return SEGMENT_REGISTER;
778   case XED_REG_DS:
779     *v3_reg = (addr_t)&(info->segments.ds);
780     return SEGMENT_REGISTER;
781   case XED_REG_ES:
782     *v3_reg = (addr_t)&(info->segments.es);
783     return SEGMENT_REGISTER;
784   case XED_REG_SS:
785     *v3_reg = (addr_t)&(info->segments.ss);
786     return SEGMENT_REGISTER;
787   case XED_REG_FS:
788     *v3_reg = (addr_t)&(info->segments.fs);
789     return SEGMENT_REGISTER;
790   case XED_REG_GS:
791     *v3_reg = (addr_t)&(info->segments.gs);
792     return SEGMENT_REGISTER;
793
794
795   case XED_REG_GDTR:
796   case XED_REG_LDTR:
797   case XED_REG_IDTR:
798   case XED_REG_TR:
799     PrintError("Segment selector operand... Don't know how to handle this...\n");
800     return -1;
801
802     /* 
803      *  DEBUG REGS
804      */
805   case XED_REG_DR0:
806   case XED_REG_DR1:
807   case XED_REG_DR2:
808   case XED_REG_DR3:
809   case XED_REG_DR4:
810   case XED_REG_DR5:
811   case XED_REG_DR6:
812   case XED_REG_DR7:
813   case XED_REG_DR8:
814   case XED_REG_DR9:
815   case XED_REG_DR10:
816   case XED_REG_DR11:
817   case XED_REG_DR12:
818   case XED_REG_DR13:
819   case XED_REG_DR14:
820   case XED_REG_DR15:
821     return -1;
822
823
824
825
826   case XED_REG_R8:
827   case XED_REG_R8D:
828   case XED_REG_R8W:
829   case XED_REG_R8B:
830
831   case XED_REG_R9:
832   case XED_REG_R9D:
833   case XED_REG_R9W:
834   case XED_REG_R9B:
835
836   case XED_REG_R10:
837   case XED_REG_R10D:
838   case XED_REG_R10W:
839   case XED_REG_R10B:
840
841   case XED_REG_R11:
842   case XED_REG_R11D:
843   case XED_REG_R11W:
844   case XED_REG_R11B:
845
846   case XED_REG_R12:
847   case XED_REG_R12D:
848   case XED_REG_R12W:
849   case XED_REG_R12B:
850
851   case XED_REG_R13:
852   case XED_REG_R13D:
853   case XED_REG_R13W:
854   case XED_REG_R13B:
855
856   case XED_REG_R14:
857   case XED_REG_R14D:
858   case XED_REG_R14W:
859   case XED_REG_R14B:
860
861   case XED_REG_R15:
862   case XED_REG_R15D:
863   case XED_REG_R15W:
864   case XED_REG_R15B:
865
866   case XED_REG_XMM0:
867   case XED_REG_XMM1:
868   case XED_REG_XMM2:
869   case XED_REG_XMM3:
870   case XED_REG_XMM4:
871   case XED_REG_XMM5:
872   case XED_REG_XMM6:
873   case XED_REG_XMM7:
874   case XED_REG_XMM8:
875   case XED_REG_XMM9:
876   case XED_REG_XMM10:
877   case XED_REG_XMM11:
878   case XED_REG_XMM12:
879   case XED_REG_XMM13:
880   case XED_REG_XMM14:
881   case XED_REG_XMM15:
882
883   case XED_REG_MMX0:
884   case XED_REG_MMX1:
885   case XED_REG_MMX2:
886   case XED_REG_MMX3:
887   case XED_REG_MMX4:
888   case XED_REG_MMX5:
889   case XED_REG_MMX6:
890   case XED_REG_MMX7:
891
892   case XED_REG_ST0:
893   case XED_REG_ST1:
894   case XED_REG_ST2:
895   case XED_REG_ST3:
896   case XED_REG_ST4:
897   case XED_REG_ST5:
898   case XED_REG_ST6:
899   case XED_REG_ST7:
900
901   case XED_REG_ONE:
902   case XED_REG_STACKPUSH:
903   case XED_REG_STACKPOP:
904     
905   case XED_REG_TSC:
906   case XED_REG_TSCAUX:
907   case XED_REG_MSRS:
908
909   case XED_REG_X87CONTROL:
910   case XED_REG_X87STATUS:
911   case XED_REG_X87TOP:
912   case XED_REG_X87TAG:
913   case XED_REG_X87PUSH:
914   case XED_REG_X87POP:
915   case XED_REG_X87POP2:
916
917   case XED_REG_MXCSR:
918
919   case XED_REG_TMP0:
920   case XED_REG_TMP1:
921   case XED_REG_TMP2:
922   case XED_REG_TMP3:
923   case XED_REG_TMP4:
924   case XED_REG_TMP5:
925   case XED_REG_TMP6:
926   case XED_REG_TMP7:
927   case XED_REG_TMP8:
928   case XED_REG_TMP9:
929   case XED_REG_TMP10:
930   case XED_REG_TMP11:
931   case XED_REG_TMP12:
932   case XED_REG_TMP13:
933   case XED_REG_TMP14:
934   case XED_REG_TMP15:
935
936   case XED_REG_LAST:
937
938   case XED_REG_ERROR:
939     // error??
940     return -1;
941
942   }
943
944
945   return 0;
946 }
947
948
949
950 static int get_opcode(xed_iform_enum_t iform, addr_t * opcode) {
951
952   switch (iform) {
953   case XED_IFORM_MOV_CR_GPR64_CR:
954   case XED_IFORM_MOV_CR_GPR32_CR:
955     *opcode = (addr_t)&V3_OPCODE_MOVCR2;
956     break;
957
958   case XED_IFORM_MOV_CR_CR_GPR64:
959   case XED_IFORM_MOV_CR_CR_GPR32:
960     *opcode = (addr_t)&V3_OPCODE_MOV2CR;
961     break;
962
963
964   case XED_IFORM_LMSW_GPR16:
965     *opcode = (addr_t)&V3_OPCODE_LMSW;
966     break;
967
968   case XED_IFORM_CLTS:
969     *opcode = (addr_t)&V3_OPCODE_CLTS;
970     break;
971
972   default:
973     *opcode = 0;
974     return -1;
975   }
976
977   return 0;
978 }