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