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