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.


64 bit guests initially supported
[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
27 #else
28
29 #include <palacios/vmm_decoder.h>
30 #include <palacios/vmm_xed.h>
31 #include <xed/xed-interface.h>
32 #include <palacios/vm_guest.h>
33 #include <palacios/vmm.h>
34 #endif
35
36
37
38 #ifndef DEBUG_XED
39 #undef PrintDebug
40 #define PrintDebug(fmt, args...)
41 #endif
42
43
44
45
46 static uint_t tables_inited = 0;
47
48
49 #define GPR_REGISTER     0
50 #define SEGMENT_REGISTER 1
51 #define CTRL_REGISTER    2
52 #define DEBUG_REGISTER   3
53
54
55
56 /* Disgusting mask hack...
57    I can't think right now, so we'll do it this way...
58 */
59 static const ullong_t mask_1 = 0x00000000000000ffLL;
60 static const ullong_t mask_2 = 0x000000000000ffffLL;
61 static const ullong_t mask_4 = 0x00000000ffffffffLL;
62 static const ullong_t mask_8 = 0xffffffffffffffffLL;
63
64
65 #define MASK(val, length) ({                    \
66       ullong_t mask = 0x0LL;                    \
67       switch (length) {                         \
68       case 1:                                   \
69         mask = mask_1;                          \
70         break;                                  \
71       case 2:                                   \
72         mask = mask_2;                          \
73         break;                                  \
74       case 4:                                   \
75         mask = mask_4;                          \
76         break;                                  \
77       case 8:                                   \
78         mask = mask_8;                          \
79         break;                                  \
80       }                                         \
81       val & mask;})                             \
82
83 struct memory_operand {
84   uint_t segment_size;
85   addr_t segment;
86   uint_t base_size;
87   addr_t base;
88   uint_t index_size;
89   addr_t index;
90   addr_t scale;
91   uint_t displacement_size;
92   ullong_t displacement;
93 };
94
95
96
97
98 static v3_op_type_t get_opcode(xed_iform_enum_t iform);
99
100 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);
101 static int get_memory_operand(struct guest_info * info,  xed_decoded_inst_t * xed_instr, uint_t index, struct x86_operand * operand);
102
103 static int set_decoder_mode(struct guest_info * info, xed_state_t * state) {
104   switch (info->cpu_mode) {
105   case REAL:
106     if (state->mmode != XED_MACHINE_MODE_LEGACY_16) {
107       xed_state_init(state,
108                      XED_MACHINE_MODE_LEGACY_16, 
109                      XED_ADDRESS_WIDTH_16b, 
110                      XED_ADDRESS_WIDTH_16b); 
111     }
112    break;
113   case PROTECTED:
114   case PROTECTED_PAE:
115   case LONG_32_COMPAT:
116     if (state->mmode != XED_MACHINE_MODE_LEGACY_32) {
117       xed_state_init(state,
118                      XED_MACHINE_MODE_LEGACY_32, 
119                      XED_ADDRESS_WIDTH_32b, 
120                      XED_ADDRESS_WIDTH_32b);
121     }
122     break;
123   case LONG:
124     if (state->mmode != XED_MACHINE_MODE_LONG_64) {    
125       state->mmode = XED_MACHINE_MODE_LONG_64;
126     }
127     break;
128   default:
129     PrintError("Unsupported CPU mode: %d\n", info->cpu_mode);
130     return -1;
131   }
132   return 0;
133 }
134
135 static int is_flags_reg(xed_reg_enum_t xed_reg) {
136   switch (xed_reg) {
137   case XED_REG_FLAGS:
138   case XED_REG_EFLAGS:
139   case XED_REG_RFLAGS:
140     return 1;
141   default:
142     return 0;
143   }
144 }
145
146
147
148 int v3_init_decoder(struct guest_info * info) {
149   // Global library initialization, only do it once
150   if (tables_inited == 0) {
151     xed_tables_init();
152     tables_inited = 1;
153   }
154
155   xed_state_t * decoder_state = (xed_state_t *)V3_Malloc(sizeof(xed_state_t));
156   xed_state_zero(decoder_state);
157
158   info->decoder_state = decoder_state;
159
160   return 0;
161 }
162
163
164
165 int v3_basic_mem_decode(struct guest_info * info, addr_t instr_ptr, struct basic_instr_info * instr_info) {
166   xed_decoded_inst_t xed_instr;
167   xed_error_enum_t xed_error;
168   
169
170   if (set_decoder_mode(info, info->decoder_state) == -1) {
171     PrintError("Could not set decoder mode\n");
172     return -1;
173   }
174
175
176   xed_decoded_inst_zero_set_mode(&xed_instr, info->decoder_state);
177
178   xed_error = xed_decode(&xed_instr, 
179                          REINTERPRET_CAST(const xed_uint8_t *, instr_ptr), 
180                          XED_MAX_INSTRUCTION_BYTES);
181
182   if (xed_error != XED_ERROR_NONE) {
183     PrintError("Xed error: %s\n", xed_error_enum_t2str(xed_error));
184     return -1;
185   }
186
187   instr_info->instr_length = xed_decoded_inst_get_length(&xed_instr);
188
189
190  if (xed_decoded_inst_number_of_memory_operands(&xed_instr) == 0) {
191    PrintError("Tried to decode memory operation with no memory operands\n");
192    return -1;
193  }
194
195  instr_info->op_size = xed_decoded_inst_get_memory_operand_length(&xed_instr, 0);
196
197
198  xed_category_enum_t cat = xed_decoded_inst_get_category(&xed_instr);
199  if (cat == XED_CATEGORY_STRINGOP) {
200    instr_info->str_op = 1;
201  } else {
202    instr_info->str_op = 0;
203  }
204
205  xed_operand_values_t * operands = xed_decoded_inst_operands(&xed_instr);
206  if (xed_operand_values_has_real_rep(operands)) {
207    instr_info->has_rep = 1;
208  } else {
209    instr_info->has_rep = 0;
210  }
211
212  return 0;
213 }
214
215
216 static int decode_string_op(struct guest_info * info, 
217                             xed_decoded_inst_t * xed_instr,  const xed_inst_t * xi,
218                             struct x86_instr * instr) {
219
220   PrintDebug("String operation\n");
221
222   if (instr->op_type == V3_OP_MOVS) {
223     instr->num_operands = 2;
224
225     if (get_memory_operand(info, xed_instr, 0, &(instr->dst_operand)) == -1) {
226       PrintError("Could not get Destination memory operand\n");
227       return -1;
228     }
229
230     if (get_memory_operand(info, xed_instr, 1, &(instr->src_operand)) == -1) {
231       PrintError("Could not get Source memory operand\n");
232       return -1;
233     }
234
235     if (instr->prefixes.rep == 1) {
236       addr_t reg_addr = 0;
237       uint_t reg_length = 0;
238
239       xed_reg_to_v3_reg(info, xed_decoded_inst_get_reg(xed_instr, XED_OPERAND_REG0), &reg_addr, &reg_length);
240       instr->str_op_length = MASK(*(addr_t *)reg_addr, reg_length);
241     } else {
242       instr->str_op_length = 1;
243     }
244
245   }
246
247   return 0;
248 }
249
250
251
252 int v3_decode(struct guest_info * info, addr_t instr_ptr, struct x86_instr * instr) {
253   xed_decoded_inst_t xed_instr;
254   xed_error_enum_t xed_error;
255
256
257   v3_get_prefixes((uchar_t *)instr_ptr, &(instr->prefixes));
258
259   if (set_decoder_mode(info, info->decoder_state) == -1) {
260     PrintError("Could not set decoder mode\n");
261     return -1;
262   }
263
264   xed_decoded_inst_zero_set_mode(&xed_instr, info->decoder_state);
265
266   xed_error = xed_decode(&xed_instr, 
267                          REINTERPRET_CAST(const xed_uint8_t *, instr_ptr), 
268                          XED_MAX_INSTRUCTION_BYTES);
269
270
271   if (xed_error != XED_ERROR_NONE) {
272     PrintError("Xed error: %s\n", xed_error_enum_t2str(xed_error));
273     return -1;
274   }
275
276   const xed_inst_t * xi = xed_decoded_inst_inst(&xed_instr);
277   
278   instr->instr_length = xed_decoded_inst_get_length(&xed_instr);
279
280
281   xed_iform_enum_t iform = xed_decoded_inst_get_iform_enum(&xed_instr);
282
283 #ifdef DEBUG_XED
284   xed_iclass_enum_t iclass = xed_decoded_inst_get_iclass(&xed_instr);
285
286   PrintDebug("iform=%s, iclass=%s\n", xed_iform_enum_t2str(iform), xed_iclass_enum_t2str(iclass));
287 #endif
288
289
290   if ((instr->op_type = get_opcode(iform)) == V3_INVALID_OP) {
291     PrintError("Could not get opcode. (iform=%s)\n", xed_iform_enum_t2str(iform));
292     return -1;
293   }
294
295
296   // We special case the string operations...
297   if (xed_decoded_inst_get_category(&xed_instr) == XED_CATEGORY_STRINGOP) {
298     instr->is_str_op = 1;
299     return decode_string_op(info, &xed_instr, xi, instr); 
300   } else {
301     instr->is_str_op = 0;
302     instr->str_op_length = 0;
303   }
304
305
306   instr->num_operands = xed_decoded_inst_noperands(&xed_instr);
307
308   if (instr->num_operands > 3) {
309     PrintDebug("Special Case Not Handled\n");
310     return -1;
311     // special case
312   } else if (instr->num_operands == 3) {
313     const xed_operand_t * op = xed_inst_operand(xi, 2);
314     xed_operand_enum_t op_enum = xed_operand_name(op);
315
316     if ((!xed_operand_is_register(op_enum)) ||
317         (!is_flags_reg(xed_decoded_inst_get_reg(&xed_instr, op_enum)))) {
318       // special case
319       PrintError("Special Case not handled\n");
320       return -1;
321     }
322   }
323
324
325
326   //PrintDebug("Number of operands: %d\n", instr->num_operands);
327   //PrintDebug("INSTR length: %d\n", instr->instr_length);
328
329   // set first operand
330   if (instr->num_operands >= 1) {
331     const xed_operand_t * op = xed_inst_operand(xi, 0);
332     xed_operand_enum_t op_enum = xed_operand_name(op);
333
334     struct x86_operand * v3_op = NULL;
335
336     if (xed_operand_written(op)) {
337       v3_op = &(instr->dst_operand);
338     } else {
339       v3_op = &(instr->src_operand);
340     }
341
342
343     if (xed_operand_is_register(op_enum)) {
344       xed_reg_enum_t xed_reg =  xed_decoded_inst_get_reg(&xed_instr, op_enum);
345       int v3_reg_type = xed_reg_to_v3_reg(info, 
346                                           xed_reg, 
347                                           &(v3_op->operand), 
348                                           &(v3_op->size));
349
350       if (v3_reg_type == -1) {
351         PrintError("First operand is an Unhandled Operand: %s\n", xed_reg_enum_t2str(xed_reg));
352         v3_op->type = INVALID_OPERAND;
353         return -1;
354       } else if (v3_reg_type == SEGMENT_REGISTER) {
355         struct v3_segment * seg_reg = (struct v3_segment *)(v3_op->operand);
356         v3_op->operand = (addr_t)&(seg_reg->selector);
357       }
358
359       v3_op->type = REG_OPERAND;
360     } else {
361
362       switch (op_enum) {
363
364       case XED_OPERAND_MEM0:
365         {
366           if (get_memory_operand(info, &xed_instr, 0, v3_op) == -1) {
367             PrintError("Could not get first memory operand\n");
368             return -1;
369           }
370         }
371         break;
372
373       case XED_OPERAND_MEM1:
374       case XED_OPERAND_IMM1:
375         // illegal
376         PrintError("Illegal Operand Order\n");
377         return -1;
378
379
380       case XED_OPERAND_IMM0:
381       case XED_OPERAND_AGEN:
382       case XED_OPERAND_PTR:
383       case XED_OPERAND_RELBR:
384       default:
385         PrintError("Unhandled Operand Type\n");
386         return -1;
387
388
389       }
390     }
391   }
392
393   // set second operand
394   if (instr->num_operands >= 2) {
395     const xed_operand_t * op = xed_inst_operand(xi, 1);
396     //   xed_operand_type_enum_t op_type = xed_operand_type(op);
397     xed_operand_enum_t op_enum = xed_operand_name(op);
398     
399     struct x86_operand * v3_op;
400
401     if (xed_operand_written(op)) {
402       v3_op = &(instr->dst_operand);
403     } else {
404       v3_op = &(instr->src_operand);
405     }
406
407
408     if (xed_operand_is_register(op_enum)) {
409       xed_reg_enum_t xed_reg =  xed_decoded_inst_get_reg(&xed_instr, op_enum);
410       int v3_reg_type = xed_reg_to_v3_reg(info, 
411                                           xed_reg, 
412                                           &(v3_op->operand), 
413                                           &(v3_op->size));
414       if (v3_reg_type == -1) {
415         PrintError("Second operand is an Unhandled Operand: %s\n", xed_reg_enum_t2str(xed_reg));
416         v3_op->type = INVALID_OPERAND;
417         return -1;
418       } else if (v3_reg_type == SEGMENT_REGISTER) {
419         struct v3_segment * seg_reg = (struct v3_segment *)(v3_op->operand);
420         v3_op->operand = (addr_t)&(seg_reg->selector);
421       }
422
423       v3_op->type = REG_OPERAND;
424     
425
426     } else {
427
428       switch (op_enum) {
429
430       case XED_OPERAND_MEM0:
431         {
432           if (get_memory_operand(info, &xed_instr, 0, v3_op) == -1) {
433             PrintError("Could not get first memory operand\n");
434             return -1;
435           }
436         }
437         break;
438
439       case XED_OPERAND_IMM0:
440         {
441           instr->src_operand.size = xed_decoded_inst_get_immediate_width(&xed_instr);
442
443           if (instr->src_operand.size > 4) {
444             PrintError("Unhandled 64 bit immediates\n");
445             return -1;
446           }
447           instr->src_operand.operand = xed_decoded_inst_get_unsigned_immediate(&xed_instr);
448
449           instr->src_operand.type = IMM_OPERAND;
450
451         }
452         break;
453
454       case XED_OPERAND_MEM1:
455       case XED_OPERAND_IMM1:
456         // illegal
457         PrintError("Illegal Operand Order\n");
458         return -1;
459         
460       case XED_OPERAND_AGEN:
461       case XED_OPERAND_PTR:
462       case XED_OPERAND_RELBR:
463       default:
464         PrintError("Unhandled Operand Type\n");
465         return -1;
466       }
467     }
468
469   }
470
471   // set third operand
472   if (instr->num_operands >= 3) {
473     const xed_operand_t * op = xed_inst_operand(xi, 2);
474     xed_operand_type_enum_t op_type = xed_operand_type(op);
475     xed_operand_enum_t op_enum = xed_operand_name(op);
476
477     if (xed_operand_is_register(op_enum)) {
478       xed_reg_enum_t xed_reg =  xed_decoded_inst_get_reg(&xed_instr, op_enum);
479       int v3_reg_type = xed_reg_to_v3_reg(info, 
480                                           xed_reg, 
481                                           &(instr->third_operand.operand), 
482                                           &(instr->third_operand.size));
483
484       if (v3_reg_type == -1) {
485         PrintError("Third operand is an Unhandled Operand: %s\n", xed_reg_enum_t2str(xed_reg));
486         instr->third_operand.type = INVALID_OPERAND;
487         return -1;
488       } else if (v3_reg_type == SEGMENT_REGISTER) {
489         struct v3_segment * seg_reg = (struct v3_segment *)(instr->third_operand.operand);
490         instr->third_operand.operand = (addr_t)&(seg_reg->selector);
491       }
492
493
494       instr->third_operand.type = REG_OPERAND;
495
496
497     } else {
498       PrintError("Unhandled third operand type %s\n", xed_operand_type_enum_t2str(op_type));
499       return -1;
500     }
501
502
503   }
504
505
506
507     return 0;
508 }
509
510
511 int v3_encode(struct guest_info * info, struct x86_instr * instr, char * instr_buf) {
512
513   return -1;
514 }
515
516
517
518
519
520 static int get_memory_operand(struct guest_info * info,  xed_decoded_inst_t * xed_instr, uint_t op_index, struct x86_operand * operand) {
521   struct memory_operand mem_op;
522
523   addr_t seg;
524   addr_t base;
525   addr_t scale;
526   addr_t index;
527   ullong_t displacement;
528   // struct v3_segment * seg_reg;
529
530
531
532
533   memset((void*)&mem_op, '\0', sizeof(struct memory_operand));
534
535   xed_reg_enum_t xed_seg = xed_decoded_inst_get_seg_reg(xed_instr, op_index);
536   if (xed_seg != XED_REG_INVALID) {
537     struct v3_segment *tmp_segment;
538     if (xed_reg_to_v3_reg(info, xed_seg, (addr_t *)&tmp_segment, &(mem_op.segment_size)) == -1) {
539       PrintError("Unhandled Segment Register\n");
540       return -1;
541     }
542     mem_op.segment = tmp_segment->base;
543   }
544
545   xed_reg_enum_t xed_base = xed_decoded_inst_get_base_reg(xed_instr, op_index);
546   if (xed_base != XED_REG_INVALID) {
547     addr_t base_reg;
548     if (xed_reg_to_v3_reg(info, xed_base, &base_reg, &(mem_op.base_size)) == -1) {
549       PrintError("Unhandled Base register\n");
550       return -1;
551     }
552     mem_op.base = *(addr_t *)base_reg;
553   }
554
555   
556
557   xed_reg_enum_t xed_idx = xed_decoded_inst_get_index_reg(xed_instr, op_index);
558   if ((op_index == 0) && (xed_idx != XED_REG_INVALID)) {
559     addr_t index_reg;
560     
561     if (xed_reg_to_v3_reg(info, xed_idx, &index_reg, &(mem_op.index_size)) == -1) {
562       PrintError("Unhandled Index Register\n");
563       return -1;
564     }
565
566     mem_op.index= *(addr_t *)index_reg;
567
568     xed_uint_t xed_scale = xed_decoded_inst_get_scale(xed_instr, op_index);
569     if (xed_scale != 0) {
570       mem_op.scale = xed_scale;
571     }
572   }
573
574
575   xed_uint_t disp_bits = xed_decoded_inst_get_memory_displacement_width(xed_instr, op_index);
576   if (disp_bits) {
577     xed_int64_t xed_disp = xed_decoded_inst_get_memory_displacement(xed_instr, op_index);
578
579     mem_op.displacement_size = disp_bits;
580     mem_op.displacement = xed_disp;
581   }
582
583   operand->type = MEM_OPERAND;
584   operand->size = xed_decoded_inst_get_memory_operand_length(xed_instr, op_index);
585   
586   
587
588   PrintDebug("Struct: Seg=%p, base=%p, index=%p, scale=%p, displacement=%p (size=%d)\n", 
589              (void *)mem_op.segment, (void*)mem_op.base, (void *)mem_op.index, 
590              (void *)mem_op.scale, (void *)(addr_t)mem_op.displacement, mem_op.displacement_size);
591
592
593   PrintDebug("operand size: %d\n", operand->size);
594
595   seg = MASK(mem_op.segment, mem_op.segment_size);
596   base = MASK(mem_op.base, mem_op.base_size);
597   index = MASK(mem_op.index, mem_op.index_size);
598   scale = mem_op.scale;
599   displacement = MASK(mem_op.displacement, mem_op.displacement_size);
600
601   PrintDebug("Seg=%p, base=%p, index=%p, scale=%p, displacement=%p\n", 
602              (void *)seg, (void *)base, (void *)index, (void *)scale, (void *)(addr_t)displacement);
603   
604   operand->operand = seg + base + (scale * index) + displacement;
605   return 0;
606 }
607
608
609 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) {
610
611   PrintError("Xed Register: %s\n", xed_reg_enum_t2str(xed_reg));
612
613   switch (xed_reg) {
614   case XED_REG_INVALID:
615     *v3_reg = 0;
616     *reg_len = 0;
617     return -1;
618
619     /* 
620      * GPRs
621      */
622   case XED_REG_RAX: 
623     *v3_reg = (addr_t)&(info->vm_regs.rax);
624     *reg_len = 8;
625     return GPR_REGISTER;
626   case XED_REG_EAX:
627     *v3_reg = (addr_t)&(info->vm_regs.rax);
628     *reg_len = 4;
629     return GPR_REGISTER;
630   case XED_REG_AX:
631     *v3_reg = (addr_t)&(info->vm_regs.rax);
632     *reg_len = 2;
633     return GPR_REGISTER;
634   case XED_REG_AH:
635     *v3_reg = (addr_t)(&(info->vm_regs.rax)) + 1;
636     *reg_len = 1;
637     return GPR_REGISTER;
638   case XED_REG_AL:
639     *v3_reg = (addr_t)&(info->vm_regs.rax);
640     *reg_len = 1;
641     return GPR_REGISTER;
642
643   case XED_REG_RCX: 
644     *v3_reg = (addr_t)&(info->vm_regs.rcx);
645     *reg_len = 8;
646     return GPR_REGISTER;
647   case XED_REG_ECX:
648     *v3_reg = (addr_t)&(info->vm_regs.rcx);
649     *reg_len = 4;
650     return GPR_REGISTER;
651   case XED_REG_CX:
652     *v3_reg = (addr_t)&(info->vm_regs.rcx);
653     *reg_len = 2;
654     return GPR_REGISTER;
655   case XED_REG_CH:
656     *v3_reg = (addr_t)(&(info->vm_regs.rcx)) + 1;
657     *reg_len = 1;
658     return GPR_REGISTER;
659   case XED_REG_CL:
660     *v3_reg = (addr_t)&(info->vm_regs.rcx);
661     *reg_len = 1;
662     return GPR_REGISTER;
663
664   case XED_REG_RDX: 
665     *v3_reg = (addr_t)&(info->vm_regs.rdx);
666     *reg_len = 8;
667     return GPR_REGISTER;
668   case XED_REG_EDX:
669     *v3_reg = (addr_t)&(info->vm_regs.rdx);
670     *reg_len = 4;
671     return GPR_REGISTER;
672   case XED_REG_DX:
673     *v3_reg = (addr_t)&(info->vm_regs.rdx);
674     *reg_len = 2;
675     return GPR_REGISTER;
676   case XED_REG_DH:
677     *v3_reg = (addr_t)(&(info->vm_regs.rdx)) + 1;
678     *reg_len = 1;
679     return GPR_REGISTER;
680   case XED_REG_DL:
681     *v3_reg = (addr_t)&(info->vm_regs.rdx);
682     *reg_len = 1;
683     return GPR_REGISTER;
684
685   case XED_REG_RBX: 
686     *v3_reg = (addr_t)&(info->vm_regs.rbx);
687     *reg_len = 8;
688     return GPR_REGISTER;
689   case XED_REG_EBX:
690     *v3_reg = (addr_t)&(info->vm_regs.rbx);
691     *reg_len = 4;
692     return GPR_REGISTER;
693   case XED_REG_BX:
694     *v3_reg = (addr_t)&(info->vm_regs.rbx);
695     *reg_len = 2;
696     return GPR_REGISTER;
697   case XED_REG_BH:
698     *v3_reg = (addr_t)(&(info->vm_regs.rbx)) + 1;
699     *reg_len = 1;
700     return GPR_REGISTER;
701   case XED_REG_BL:
702     *v3_reg = (addr_t)&(info->vm_regs.rbx);
703     *reg_len = 1;
704     return GPR_REGISTER;
705
706
707   case XED_REG_RSP:
708     *v3_reg = (addr_t)&(info->vm_regs.rsp);
709     *reg_len = 8;
710     return GPR_REGISTER;
711   case XED_REG_ESP:
712     *v3_reg = (addr_t)&(info->vm_regs.rsp);
713     *reg_len = 4;
714     return GPR_REGISTER;
715   case XED_REG_SP:
716     *v3_reg = (addr_t)&(info->vm_regs.rsp);
717     *reg_len = 2;
718     return GPR_REGISTER;
719   case XED_REG_SPL:
720     *v3_reg = (addr_t)&(info->vm_regs.rsp);
721     *reg_len = 1;
722     return GPR_REGISTER;
723
724   case XED_REG_RBP:
725     *v3_reg = (addr_t)&(info->vm_regs.rbp);
726     *reg_len = 8;
727     return GPR_REGISTER;
728   case XED_REG_EBP:
729     *v3_reg = (addr_t)&(info->vm_regs.rbp);
730     *reg_len = 4;
731     return GPR_REGISTER;
732   case XED_REG_BP:
733     *v3_reg = (addr_t)&(info->vm_regs.rbp);
734     *reg_len = 2;
735     return GPR_REGISTER;
736   case XED_REG_BPL:
737     *v3_reg = (addr_t)&(info->vm_regs.rbp);
738     *reg_len = 1;
739     return GPR_REGISTER;
740
741
742
743   case XED_REG_RSI:
744     *v3_reg = (addr_t)&(info->vm_regs.rsi);
745     *reg_len = 8;
746     return GPR_REGISTER;
747   case XED_REG_ESI:
748     *v3_reg = (addr_t)&(info->vm_regs.rsi);
749     *reg_len = 4;
750     return GPR_REGISTER;
751   case XED_REG_SI:
752     *v3_reg = (addr_t)&(info->vm_regs.rsi);
753     *reg_len = 2;
754     return GPR_REGISTER;
755   case XED_REG_SIL:
756     *v3_reg = (addr_t)&(info->vm_regs.rsi);
757     *reg_len = 1;
758     return GPR_REGISTER;
759
760
761   case XED_REG_RDI:
762     *v3_reg = (addr_t)&(info->vm_regs.rdi);
763     *reg_len = 8;
764     return GPR_REGISTER;
765   case XED_REG_EDI:
766     *v3_reg = (addr_t)&(info->vm_regs.rdi);
767     *reg_len = 4;
768     return GPR_REGISTER;
769   case XED_REG_DI:
770     *v3_reg = (addr_t)&(info->vm_regs.rdi);
771     *reg_len = 2;
772     return GPR_REGISTER;
773   case XED_REG_DIL:
774     *v3_reg = (addr_t)&(info->vm_regs.rdi);
775     *reg_len = 1;
776     return GPR_REGISTER;
777
778
779
780
781
782   case XED_REG_R8:
783     *v3_reg = (addr_t)&(info->vm_regs.r8);
784     *reg_len = 8;
785     return GPR_REGISTER;
786   case XED_REG_R8D:
787     *v3_reg = (addr_t)&(info->vm_regs.r8);
788     *reg_len = 4;
789     return GPR_REGISTER;
790   case XED_REG_R8W:
791     *v3_reg = (addr_t)&(info->vm_regs.r8);
792     *reg_len = 2;
793     return GPR_REGISTER;
794   case XED_REG_R8B:
795     *v3_reg = (addr_t)&(info->vm_regs.r8);
796     *reg_len = 1;
797     return GPR_REGISTER;
798
799   case XED_REG_R9:
800     *v3_reg = (addr_t)&(info->vm_regs.r9);
801     *reg_len = 8;
802     return GPR_REGISTER;
803   case XED_REG_R9D:
804     *v3_reg = (addr_t)&(info->vm_regs.r9);
805     *reg_len = 4;
806     return GPR_REGISTER;
807   case XED_REG_R9W:
808     *v3_reg = (addr_t)&(info->vm_regs.r9);
809     *reg_len = 2;
810     return GPR_REGISTER;
811   case XED_REG_R9B:
812     *v3_reg = (addr_t)&(info->vm_regs.r9);
813     *reg_len = 1;
814     return GPR_REGISTER;
815
816   case XED_REG_R10:
817     *v3_reg = (addr_t)&(info->vm_regs.r10);
818     *reg_len = 8;
819     return GPR_REGISTER;
820   case XED_REG_R10D:
821     *v3_reg = (addr_t)&(info->vm_regs.r10);
822     *reg_len = 4;
823     return GPR_REGISTER;
824   case XED_REG_R10W:
825     *v3_reg = (addr_t)&(info->vm_regs.r10);
826     *reg_len = 2;
827     return GPR_REGISTER;
828   case XED_REG_R10B:
829     *v3_reg = (addr_t)&(info->vm_regs.r10);
830     *reg_len = 1;
831     return GPR_REGISTER;
832
833   case XED_REG_R11:
834     *v3_reg = (addr_t)&(info->vm_regs.r11);
835     *reg_len = 8;
836     return GPR_REGISTER;
837   case XED_REG_R11D:
838     *v3_reg = (addr_t)&(info->vm_regs.r11);
839     *reg_len = 4;
840     return GPR_REGISTER;
841   case XED_REG_R11W:
842     *v3_reg = (addr_t)&(info->vm_regs.r11);
843     *reg_len = 2;
844     return GPR_REGISTER;
845   case XED_REG_R11B:
846     *v3_reg = (addr_t)&(info->vm_regs.r11);
847     *reg_len = 1;
848     return GPR_REGISTER;
849
850   case XED_REG_R12:
851     *v3_reg = (addr_t)&(info->vm_regs.r12);
852     *reg_len = 8;
853     return GPR_REGISTER;
854   case XED_REG_R12D:
855     *v3_reg = (addr_t)&(info->vm_regs.r12);
856     *reg_len = 4;
857     return GPR_REGISTER;
858   case XED_REG_R12W:
859     *v3_reg = (addr_t)&(info->vm_regs.r12);
860     *reg_len = 2;
861     return GPR_REGISTER;
862   case XED_REG_R12B:
863     *v3_reg = (addr_t)&(info->vm_regs.r12);
864     *reg_len = 1;
865     return GPR_REGISTER;
866
867   case XED_REG_R13:
868     *v3_reg = (addr_t)&(info->vm_regs.r13);
869     *reg_len = 8;
870     return GPR_REGISTER;
871   case XED_REG_R13D:
872     *v3_reg = (addr_t)&(info->vm_regs.r13);
873     *reg_len = 4;
874     return GPR_REGISTER;
875   case XED_REG_R13W:
876     *v3_reg = (addr_t)&(info->vm_regs.r13);
877     *reg_len = 2;
878     return GPR_REGISTER;
879   case XED_REG_R13B:
880     *v3_reg = (addr_t)&(info->vm_regs.r13);
881     *reg_len = 1;
882     return GPR_REGISTER;
883
884   case XED_REG_R14:
885     *v3_reg = (addr_t)&(info->vm_regs.r14);
886     *reg_len = 8;
887     return GPR_REGISTER;
888   case XED_REG_R14D:
889     *v3_reg = (addr_t)&(info->vm_regs.r14);
890     *reg_len = 4;
891     return GPR_REGISTER;
892   case XED_REG_R14W:
893     *v3_reg = (addr_t)&(info->vm_regs.r14);
894     *reg_len = 2;
895     return GPR_REGISTER;
896   case XED_REG_R14B:
897     *v3_reg = (addr_t)&(info->vm_regs.r14);
898     *reg_len = 1;
899     return GPR_REGISTER;
900
901   case XED_REG_R15:
902     *v3_reg = (addr_t)&(info->vm_regs.r15);
903     *reg_len = 8;
904     return GPR_REGISTER;
905   case XED_REG_R15D:
906     *v3_reg = (addr_t)&(info->vm_regs.r15);
907     *reg_len = 4;
908     return GPR_REGISTER;
909   case XED_REG_R15W:
910     *v3_reg = (addr_t)&(info->vm_regs.r15);
911     *reg_len = 2;
912     return GPR_REGISTER;
913   case XED_REG_R15B:
914     *v3_reg = (addr_t)&(info->vm_regs.r15);
915     *reg_len = 1;
916     return GPR_REGISTER;
917
918
919     /* 
920      *  CTRL REGS
921      */
922   case XED_REG_RIP:
923     *v3_reg = (addr_t)&(info->rip);
924     *reg_len = 8;
925     return CTRL_REGISTER;
926   case XED_REG_EIP:
927     *v3_reg = (addr_t)&(info->rip);
928     *reg_len = 4;
929     return CTRL_REGISTER;  
930   case XED_REG_IP:
931     *v3_reg = (addr_t)&(info->rip);
932     *reg_len = 2;
933     return CTRL_REGISTER;
934
935   case XED_REG_FLAGS:
936     *v3_reg = (addr_t)&(info->ctrl_regs.rflags);
937     *reg_len = 2;
938     return CTRL_REGISTER;
939   case XED_REG_EFLAGS:
940     *v3_reg = (addr_t)&(info->ctrl_regs.rflags);
941     *reg_len = 4;
942     return CTRL_REGISTER;
943   case XED_REG_RFLAGS:
944     *v3_reg = (addr_t)&(info->ctrl_regs.rflags);
945     *reg_len = 8;
946     return CTRL_REGISTER;
947
948   case XED_REG_CR0:
949     *v3_reg = (addr_t)&(info->ctrl_regs.cr0);
950     *reg_len = 4;
951     return CTRL_REGISTER;
952   case XED_REG_CR2:
953     *v3_reg = (addr_t)&(info->ctrl_regs.cr2);
954     *reg_len = 4;
955     return CTRL_REGISTER;
956   case XED_REG_CR3:
957     *v3_reg = (addr_t)&(info->ctrl_regs.cr3);
958     *reg_len = 4;
959     return CTRL_REGISTER;
960   case XED_REG_CR4:
961     *v3_reg = (addr_t)&(info->ctrl_regs.cr4);
962    *reg_len = 4;
963     return CTRL_REGISTER;
964   case XED_REG_CR8:
965     *v3_reg = (addr_t)&(info->ctrl_regs.cr8);
966     *reg_len = 4;
967     return CTRL_REGISTER;
968
969   case XED_REG_CR1:
970   case XED_REG_CR5:
971   case XED_REG_CR6:
972   case XED_REG_CR7:
973   case XED_REG_CR9:
974   case XED_REG_CR10:
975   case XED_REG_CR11:
976   case XED_REG_CR12:
977   case XED_REG_CR13:
978   case XED_REG_CR14:
979   case XED_REG_CR15:
980     return -1;
981
982
983
984
985     /* 
986      * SEGMENT REGS
987      */
988   case XED_REG_CS:
989     *v3_reg = (addr_t)&(info->segments.cs);
990     return SEGMENT_REGISTER;
991   case XED_REG_DS:
992     *v3_reg = (addr_t)&(info->segments.ds);
993     return SEGMENT_REGISTER;
994   case XED_REG_ES:
995     *v3_reg = (addr_t)&(info->segments.es);
996     return SEGMENT_REGISTER;
997   case XED_REG_SS:
998     *v3_reg = (addr_t)&(info->segments.ss);
999     return SEGMENT_REGISTER;
1000   case XED_REG_FS:
1001     *v3_reg = (addr_t)&(info->segments.fs);
1002     return SEGMENT_REGISTER;
1003   case XED_REG_GS:
1004     *v3_reg = (addr_t)&(info->segments.gs);
1005     return SEGMENT_REGISTER;
1006
1007
1008   case XED_REG_GDTR:
1009   case XED_REG_LDTR:
1010   case XED_REG_IDTR:
1011   case XED_REG_TR:
1012     PrintError("Segment selector operand... Don't know how to handle this...\n");
1013     return -1;
1014
1015     /* 
1016      *  DEBUG REGS
1017      */
1018   case XED_REG_DR0:
1019   case XED_REG_DR1:
1020   case XED_REG_DR2:
1021   case XED_REG_DR3:
1022   case XED_REG_DR4:
1023   case XED_REG_DR5:
1024   case XED_REG_DR6:
1025   case XED_REG_DR7:
1026   case XED_REG_DR8:
1027   case XED_REG_DR9:
1028   case XED_REG_DR10:
1029   case XED_REG_DR11:
1030   case XED_REG_DR12:
1031   case XED_REG_DR13:
1032   case XED_REG_DR14:
1033   case XED_REG_DR15:
1034     return -1;
1035
1036
1037
1038
1039
1040
1041   case XED_REG_XMM0:
1042   case XED_REG_XMM1:
1043   case XED_REG_XMM2:
1044   case XED_REG_XMM3:
1045   case XED_REG_XMM4:
1046   case XED_REG_XMM5:
1047   case XED_REG_XMM6:
1048   case XED_REG_XMM7:
1049   case XED_REG_XMM8:
1050   case XED_REG_XMM9:
1051   case XED_REG_XMM10:
1052   case XED_REG_XMM11:
1053   case XED_REG_XMM12:
1054   case XED_REG_XMM13:
1055   case XED_REG_XMM14:
1056   case XED_REG_XMM15:
1057
1058   case XED_REG_MMX0:
1059   case XED_REG_MMX1:
1060   case XED_REG_MMX2:
1061   case XED_REG_MMX3:
1062   case XED_REG_MMX4:
1063   case XED_REG_MMX5:
1064   case XED_REG_MMX6:
1065   case XED_REG_MMX7:
1066
1067   case XED_REG_ST0:
1068   case XED_REG_ST1:
1069   case XED_REG_ST2:
1070   case XED_REG_ST3:
1071   case XED_REG_ST4:
1072   case XED_REG_ST5:
1073   case XED_REG_ST6:
1074   case XED_REG_ST7:
1075
1076   case XED_REG_ONE:
1077   case XED_REG_STACKPUSH:
1078   case XED_REG_STACKPOP:
1079     
1080   case XED_REG_TSC:
1081   case XED_REG_TSCAUX:
1082   case XED_REG_MSRS:
1083
1084   case XED_REG_X87CONTROL:
1085   case XED_REG_X87STATUS:
1086   case XED_REG_X87TOP:
1087   case XED_REG_X87TAG:
1088   case XED_REG_X87PUSH:
1089   case XED_REG_X87POP:
1090   case XED_REG_X87POP2:
1091
1092   case XED_REG_MXCSR:
1093
1094   case XED_REG_TMP0:
1095   case XED_REG_TMP1:
1096   case XED_REG_TMP2:
1097   case XED_REG_TMP3:
1098   case XED_REG_TMP4:
1099   case XED_REG_TMP5:
1100   case XED_REG_TMP6:
1101   case XED_REG_TMP7:
1102   case XED_REG_TMP8:
1103   case XED_REG_TMP9:
1104   case XED_REG_TMP10:
1105   case XED_REG_TMP11:
1106   case XED_REG_TMP12:
1107   case XED_REG_TMP13:
1108   case XED_REG_TMP14:
1109   case XED_REG_TMP15:
1110
1111   case XED_REG_LAST:
1112
1113   case XED_REG_ERROR:
1114     // error??
1115     return -1;
1116
1117   }
1118
1119
1120   return 0;
1121 }
1122
1123
1124
1125 static v3_op_type_t get_opcode(xed_iform_enum_t iform) {
1126
1127   switch (iform) {
1128
1129     /* Control Instructions */
1130
1131   case XED_IFORM_MOV_CR_GPR64_CR:
1132   case XED_IFORM_MOV_CR_GPR32_CR:
1133     return V3_OP_MOVCR2;
1134
1135   case XED_IFORM_MOV_CR_CR_GPR64:
1136   case XED_IFORM_MOV_CR_CR_GPR32:
1137     return V3_OP_MOV2CR;
1138
1139   case XED_IFORM_SMSW_GPRv:
1140     return V3_OP_SMSW;
1141
1142   case XED_IFORM_LMSW_GPR16:
1143     return V3_OP_LMSW;
1144
1145   case XED_IFORM_CLTS:
1146     return V3_OP_CLTS;
1147
1148   case XED_IFORM_INVLPG_MEMb:
1149     return V3_OP_INVLPG;
1150
1151
1152     /* Data Instructions */
1153
1154   case XED_IFORM_ADC_MEMv_GPRv:
1155   case XED_IFORM_ADC_MEMv_IMM:
1156   case XED_IFORM_ADC_MEMb_GPR8:
1157   case XED_IFORM_ADC_MEMb_IMM:
1158     return V3_OP_ADC;
1159
1160   case XED_IFORM_ADD_MEMv_GPRv:
1161   case XED_IFORM_ADD_MEMb_IMM:
1162   case XED_IFORM_ADD_MEMb_GPR8:
1163   case XED_IFORM_ADD_MEMv_IMM:
1164     return V3_OP_ADD;
1165
1166   case XED_IFORM_AND_MEMv_IMM:
1167   case XED_IFORM_AND_MEMb_GPR8:
1168   case XED_IFORM_AND_MEMv_GPRv:
1169   case XED_IFORM_AND_MEMb_IMM:
1170     return V3_OP_AND;
1171
1172   case XED_IFORM_SUB_MEMv_IMM:
1173   case XED_IFORM_SUB_MEMb_GPR8:
1174   case XED_IFORM_SUB_MEMb_IMM:
1175   case XED_IFORM_SUB_MEMv_GPRv:
1176     return V3_OP_SUB;
1177
1178   case XED_IFORM_MOV_MEMv_GPRv:
1179   case XED_IFORM_MOV_MEMb_GPR8:
1180   case XED_IFORM_MOV_MEMb_AL:
1181   case XED_IFORM_MOV_MEMv_IMM:
1182   case XED_IFORM_MOV_MEMb_IMM:
1183     return V3_OP_MOV;
1184
1185   case XED_IFORM_DEC_MEMv:
1186   case XED_IFORM_DEC_MEMb:
1187     return V3_OP_DEC;
1188
1189   case XED_IFORM_INC_MEMb:
1190   case XED_IFORM_INC_MEMv:
1191     return V3_OP_INC;
1192
1193   case XED_IFORM_OR_MEMv_IMM:
1194   case XED_IFORM_OR_MEMb_IMM:
1195   case XED_IFORM_OR_MEMv_GPRv:
1196   case XED_IFORM_OR_MEMb_GPR8:
1197     return V3_OP_OR;
1198
1199   case XED_IFORM_XOR_MEMv_GPRv:
1200   case XED_IFORM_XOR_MEMb_IMM:
1201   case XED_IFORM_XOR_MEMb_GPR8:
1202   case XED_IFORM_XOR_MEMv_IMM:
1203     return V3_OP_XOR;
1204
1205   case XED_IFORM_NEG_MEMb:
1206   case XED_IFORM_NEG_MEMv:
1207     return V3_OP_NEG;
1208
1209   case XED_IFORM_NOT_MEMv:
1210   case XED_IFORM_NOT_MEMb:
1211     return V3_OP_NOT;
1212
1213   case XED_IFORM_XCHG_MEMv_GPRv:
1214   case XED_IFORM_XCHG_MEMb_GPR8:
1215     return V3_OP_XCHG;
1216
1217   case XED_IFORM_SETB_MEMb:
1218     return V3_OP_SETB;
1219
1220   case XED_IFORM_SETBE_MEMb:
1221     return V3_OP_SETBE;
1222
1223   case XED_IFORM_SETL_MEMb:
1224     return V3_OP_SETL;
1225
1226   case XED_IFORM_SETLE_MEMb:
1227     return V3_OP_SETLE;
1228
1229   case XED_IFORM_SETNB_MEMb:
1230     return V3_OP_SETNB;
1231
1232   case XED_IFORM_SETNBE_MEMb:
1233     return V3_OP_SETNBE;
1234
1235   case XED_IFORM_SETNL_MEMb:
1236     return V3_OP_SETNL;
1237
1238   case XED_IFORM_SETNLE_MEMb:
1239     return V3_OP_SETNLE;
1240
1241   case XED_IFORM_SETNO_MEMb:
1242     return V3_OP_SETNO;
1243     
1244   case XED_IFORM_SETNP_MEMb:
1245     return V3_OP_SETNP;
1246
1247   case XED_IFORM_SETNS_MEMb:
1248     return V3_OP_SETNS;
1249
1250   case XED_IFORM_SETNZ_MEMb:
1251     return V3_OP_SETNZ;
1252
1253   case XED_IFORM_SETO_MEMb:
1254     return V3_OP_SETO;
1255     
1256   case XED_IFORM_SETP_MEMb:
1257     return V3_OP_SETP;
1258
1259   case XED_IFORM_SETS_MEMb:
1260     return V3_OP_SETS;
1261
1262   case XED_IFORM_SETZ_MEMb:
1263     return V3_OP_SETZ;
1264
1265
1266   case XED_IFORM_MOVSB:
1267   case XED_IFORM_MOVSW:
1268   case XED_IFORM_MOVSD:
1269   case XED_IFORM_MOVSQ:
1270     return V3_OP_MOVS;
1271
1272   default:
1273     return V3_INVALID_OP;
1274   }
1275 }