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.


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