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.


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