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