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