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.


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