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.


73dd4cedbdd785c040ccd181a459d580aa7adbae
[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   switch (xed_reg) {
612   case XED_REG_INVALID:
613     *v3_reg = 0;
614     *reg_len = 0;
615     return -1;
616
617     /* 
618      * GPRs
619      */
620   case XED_REG_RAX: 
621     *v3_reg = (addr_t)&(info->vm_regs.rax);
622     *reg_len = 8;
623     return GPR_REGISTER;
624   case XED_REG_EAX:
625     *v3_reg = (addr_t)&(info->vm_regs.rax);
626     *reg_len = 4;
627     return GPR_REGISTER;
628   case XED_REG_AX:
629     *v3_reg = (addr_t)&(info->vm_regs.rax);
630     *reg_len = 2;
631     return GPR_REGISTER;
632   case XED_REG_AH:
633     *v3_reg = (addr_t)(&(info->vm_regs.rax)) + 1;
634     *reg_len = 1;
635     return GPR_REGISTER;
636   case XED_REG_AL:
637     *v3_reg = (addr_t)&(info->vm_regs.rax);
638     *reg_len = 1;
639     return GPR_REGISTER;
640
641   case XED_REG_RCX: 
642     *v3_reg = (addr_t)&(info->vm_regs.rcx);
643     *reg_len = 8;
644     return GPR_REGISTER;
645   case XED_REG_ECX:
646     *v3_reg = (addr_t)&(info->vm_regs.rcx);
647     *reg_len = 4;
648     return GPR_REGISTER;
649   case XED_REG_CX:
650     *v3_reg = (addr_t)&(info->vm_regs.rcx);
651     *reg_len = 2;
652     return GPR_REGISTER;
653   case XED_REG_CH:
654     *v3_reg = (addr_t)(&(info->vm_regs.rcx)) + 1;
655     *reg_len = 1;
656     return GPR_REGISTER;
657   case XED_REG_CL:
658     *v3_reg = (addr_t)&(info->vm_regs.rcx);
659     *reg_len = 1;
660     return GPR_REGISTER;
661
662   case XED_REG_RDX: 
663     *v3_reg = (addr_t)&(info->vm_regs.rdx);
664     *reg_len = 8;
665     return GPR_REGISTER;
666   case XED_REG_EDX:
667     *v3_reg = (addr_t)&(info->vm_regs.rdx);
668     *reg_len = 4;
669     return GPR_REGISTER;
670   case XED_REG_DX:
671     *v3_reg = (addr_t)&(info->vm_regs.rdx);
672     *reg_len = 2;
673     return GPR_REGISTER;
674   case XED_REG_DH:
675     *v3_reg = (addr_t)(&(info->vm_regs.rdx)) + 1;
676     *reg_len = 1;
677     return GPR_REGISTER;
678   case XED_REG_DL:
679     *v3_reg = (addr_t)&(info->vm_regs.rdx);
680     *reg_len = 1;
681     return GPR_REGISTER;
682
683   case XED_REG_RBX: 
684     *v3_reg = (addr_t)&(info->vm_regs.rbx);
685     *reg_len = 8;
686     return GPR_REGISTER;
687   case XED_REG_EBX:
688     *v3_reg = (addr_t)&(info->vm_regs.rbx);
689     *reg_len = 4;
690     return GPR_REGISTER;
691   case XED_REG_BX:
692     *v3_reg = (addr_t)&(info->vm_regs.rbx);
693     *reg_len = 2;
694     return GPR_REGISTER;
695   case XED_REG_BH:
696     *v3_reg = (addr_t)(&(info->vm_regs.rbx)) + 1;
697     *reg_len = 1;
698     return GPR_REGISTER;
699   case XED_REG_BL:
700     *v3_reg = (addr_t)&(info->vm_regs.rbx);
701     *reg_len = 1;
702     return GPR_REGISTER;
703
704
705   case XED_REG_RSP:
706     *v3_reg = (addr_t)&(info->vm_regs.rsp);
707     *reg_len = 8;
708     return GPR_REGISTER;
709   case XED_REG_ESP:
710     *v3_reg = (addr_t)&(info->vm_regs.rsp);
711     *reg_len = 4;
712     return GPR_REGISTER;
713   case XED_REG_SP:
714     *v3_reg = (addr_t)&(info->vm_regs.rsp);
715     *reg_len = 2;
716     return GPR_REGISTER;
717   case XED_REG_SPL:
718     *v3_reg = (addr_t)&(info->vm_regs.rsp);
719     *reg_len = 1;
720     return GPR_REGISTER;
721
722   case XED_REG_RBP:
723     *v3_reg = (addr_t)&(info->vm_regs.rbp);
724     *reg_len = 8;
725     return GPR_REGISTER;
726   case XED_REG_EBP:
727     *v3_reg = (addr_t)&(info->vm_regs.rbp);
728     *reg_len = 4;
729     return GPR_REGISTER;
730   case XED_REG_BP:
731     *v3_reg = (addr_t)&(info->vm_regs.rbp);
732     *reg_len = 2;
733     return GPR_REGISTER;
734   case XED_REG_BPL:
735     *v3_reg = (addr_t)&(info->vm_regs.rbp);
736     *reg_len = 1;
737     return GPR_REGISTER;
738
739
740
741   case XED_REG_RSI:
742     *v3_reg = (addr_t)&(info->vm_regs.rsi);
743     *reg_len = 8;
744     return GPR_REGISTER;
745   case XED_REG_ESI:
746     *v3_reg = (addr_t)&(info->vm_regs.rsi);
747     *reg_len = 4;
748     return GPR_REGISTER;
749   case XED_REG_SI:
750     *v3_reg = (addr_t)&(info->vm_regs.rsi);
751     *reg_len = 2;
752     return GPR_REGISTER;
753   case XED_REG_SIL:
754     *v3_reg = (addr_t)&(info->vm_regs.rsi);
755     *reg_len = 1;
756     return GPR_REGISTER;
757
758
759   case XED_REG_RDI:
760     *v3_reg = (addr_t)&(info->vm_regs.rdi);
761     *reg_len = 8;
762     return GPR_REGISTER;
763   case XED_REG_EDI:
764     *v3_reg = (addr_t)&(info->vm_regs.rdi);
765     *reg_len = 4;
766     return GPR_REGISTER;
767   case XED_REG_DI:
768     *v3_reg = (addr_t)&(info->vm_regs.rdi);
769     *reg_len = 2;
770     return GPR_REGISTER;
771   case XED_REG_DIL:
772     *v3_reg = (addr_t)&(info->vm_regs.rdi);
773     *reg_len = 1;
774     return GPR_REGISTER;
775
776
777     /* 
778      *  CTRL REGS
779      */
780   case XED_REG_RIP:
781     *v3_reg = (addr_t)&(info->rip);
782     *reg_len = 8;
783     return CTRL_REGISTER;
784   case XED_REG_EIP:
785     *v3_reg = (addr_t)&(info->rip);
786     *reg_len = 4;
787     return CTRL_REGISTER;  
788   case XED_REG_IP:
789     *v3_reg = (addr_t)&(info->rip);
790     *reg_len = 2;
791     return CTRL_REGISTER;
792
793   case XED_REG_FLAGS:
794     *v3_reg = (addr_t)&(info->ctrl_regs.rflags);
795     *reg_len = 2;
796     return CTRL_REGISTER;
797   case XED_REG_EFLAGS:
798     *v3_reg = (addr_t)&(info->ctrl_regs.rflags);
799     *reg_len = 4;
800     return CTRL_REGISTER;
801   case XED_REG_RFLAGS:
802     *v3_reg = (addr_t)&(info->ctrl_regs.rflags);
803     *reg_len = 8;
804     return CTRL_REGISTER;
805
806   case XED_REG_CR0:
807     *v3_reg = (addr_t)&(info->ctrl_regs.cr0);
808     *reg_len = 4;
809     return CTRL_REGISTER;
810   case XED_REG_CR2:
811     *v3_reg = (addr_t)&(info->ctrl_regs.cr2);
812     *reg_len = 4;
813     return CTRL_REGISTER;
814   case XED_REG_CR3:
815     *v3_reg = (addr_t)&(info->ctrl_regs.cr3);
816     *reg_len = 4;
817     return CTRL_REGISTER;
818   case XED_REG_CR4:
819     *v3_reg = (addr_t)&(info->ctrl_regs.cr4);
820    *reg_len = 4;
821     return CTRL_REGISTER;
822   case XED_REG_CR8:
823     *v3_reg = (addr_t)&(info->ctrl_regs.cr8);
824     *reg_len = 4;
825     return CTRL_REGISTER;
826
827   case XED_REG_CR1:
828   case XED_REG_CR5:
829   case XED_REG_CR6:
830   case XED_REG_CR7:
831   case XED_REG_CR9:
832   case XED_REG_CR10:
833   case XED_REG_CR11:
834   case XED_REG_CR12:
835   case XED_REG_CR13:
836   case XED_REG_CR14:
837   case XED_REG_CR15:
838     return -1;
839
840
841
842
843     /* 
844      * SEGMENT REGS
845      */
846   case XED_REG_CS:
847     *v3_reg = (addr_t)&(info->segments.cs);
848     return SEGMENT_REGISTER;
849   case XED_REG_DS:
850     *v3_reg = (addr_t)&(info->segments.ds);
851     return SEGMENT_REGISTER;
852   case XED_REG_ES:
853     *v3_reg = (addr_t)&(info->segments.es);
854     return SEGMENT_REGISTER;
855   case XED_REG_SS:
856     *v3_reg = (addr_t)&(info->segments.ss);
857     return SEGMENT_REGISTER;
858   case XED_REG_FS:
859     *v3_reg = (addr_t)&(info->segments.fs);
860     return SEGMENT_REGISTER;
861   case XED_REG_GS:
862     *v3_reg = (addr_t)&(info->segments.gs);
863     return SEGMENT_REGISTER;
864
865
866   case XED_REG_GDTR:
867   case XED_REG_LDTR:
868   case XED_REG_IDTR:
869   case XED_REG_TR:
870     PrintError("Segment selector operand... Don't know how to handle this...\n");
871     return -1;
872
873     /* 
874      *  DEBUG REGS
875      */
876   case XED_REG_DR0:
877   case XED_REG_DR1:
878   case XED_REG_DR2:
879   case XED_REG_DR3:
880   case XED_REG_DR4:
881   case XED_REG_DR5:
882   case XED_REG_DR6:
883   case XED_REG_DR7:
884   case XED_REG_DR8:
885   case XED_REG_DR9:
886   case XED_REG_DR10:
887   case XED_REG_DR11:
888   case XED_REG_DR12:
889   case XED_REG_DR13:
890   case XED_REG_DR14:
891   case XED_REG_DR15:
892     return -1;
893
894
895
896
897   case XED_REG_R8:
898   case XED_REG_R8D:
899   case XED_REG_R8W:
900   case XED_REG_R8B:
901
902   case XED_REG_R9:
903   case XED_REG_R9D:
904   case XED_REG_R9W:
905   case XED_REG_R9B:
906
907   case XED_REG_R10:
908   case XED_REG_R10D:
909   case XED_REG_R10W:
910   case XED_REG_R10B:
911
912   case XED_REG_R11:
913   case XED_REG_R11D:
914   case XED_REG_R11W:
915   case XED_REG_R11B:
916
917   case XED_REG_R12:
918   case XED_REG_R12D:
919   case XED_REG_R12W:
920   case XED_REG_R12B:
921
922   case XED_REG_R13:
923   case XED_REG_R13D:
924   case XED_REG_R13W:
925   case XED_REG_R13B:
926
927   case XED_REG_R14:
928   case XED_REG_R14D:
929   case XED_REG_R14W:
930   case XED_REG_R14B:
931
932   case XED_REG_R15:
933   case XED_REG_R15D:
934   case XED_REG_R15W:
935   case XED_REG_R15B:
936
937   case XED_REG_XMM0:
938   case XED_REG_XMM1:
939   case XED_REG_XMM2:
940   case XED_REG_XMM3:
941   case XED_REG_XMM4:
942   case XED_REG_XMM5:
943   case XED_REG_XMM6:
944   case XED_REG_XMM7:
945   case XED_REG_XMM8:
946   case XED_REG_XMM9:
947   case XED_REG_XMM10:
948   case XED_REG_XMM11:
949   case XED_REG_XMM12:
950   case XED_REG_XMM13:
951   case XED_REG_XMM14:
952   case XED_REG_XMM15:
953
954   case XED_REG_MMX0:
955   case XED_REG_MMX1:
956   case XED_REG_MMX2:
957   case XED_REG_MMX3:
958   case XED_REG_MMX4:
959   case XED_REG_MMX5:
960   case XED_REG_MMX6:
961   case XED_REG_MMX7:
962
963   case XED_REG_ST0:
964   case XED_REG_ST1:
965   case XED_REG_ST2:
966   case XED_REG_ST3:
967   case XED_REG_ST4:
968   case XED_REG_ST5:
969   case XED_REG_ST6:
970   case XED_REG_ST7:
971
972   case XED_REG_ONE:
973   case XED_REG_STACKPUSH:
974   case XED_REG_STACKPOP:
975     
976   case XED_REG_TSC:
977   case XED_REG_TSCAUX:
978   case XED_REG_MSRS:
979
980   case XED_REG_X87CONTROL:
981   case XED_REG_X87STATUS:
982   case XED_REG_X87TOP:
983   case XED_REG_X87TAG:
984   case XED_REG_X87PUSH:
985   case XED_REG_X87POP:
986   case XED_REG_X87POP2:
987
988   case XED_REG_MXCSR:
989
990   case XED_REG_TMP0:
991   case XED_REG_TMP1:
992   case XED_REG_TMP2:
993   case XED_REG_TMP3:
994   case XED_REG_TMP4:
995   case XED_REG_TMP5:
996   case XED_REG_TMP6:
997   case XED_REG_TMP7:
998   case XED_REG_TMP8:
999   case XED_REG_TMP9:
1000   case XED_REG_TMP10:
1001   case XED_REG_TMP11:
1002   case XED_REG_TMP12:
1003   case XED_REG_TMP13:
1004   case XED_REG_TMP14:
1005   case XED_REG_TMP15:
1006
1007   case XED_REG_LAST:
1008
1009   case XED_REG_ERROR:
1010     // error??
1011     return -1;
1012
1013   }
1014
1015
1016   return 0;
1017 }
1018
1019
1020
1021 static v3_op_type_t get_opcode(xed_iform_enum_t iform) {
1022
1023   switch (iform) {
1024
1025     /* Control Instructions */
1026
1027   case XED_IFORM_MOV_CR_GPR64_CR:
1028   case XED_IFORM_MOV_CR_GPR32_CR:
1029     return V3_OP_MOVCR2;
1030
1031   case XED_IFORM_MOV_CR_CR_GPR64:
1032   case XED_IFORM_MOV_CR_CR_GPR32:
1033     return V3_OP_MOV2CR;
1034
1035   case XED_IFORM_SMSW_GPRv:
1036     return V3_OP_SMSW;
1037
1038   case XED_IFORM_LMSW_GPR16:
1039     return V3_OP_LMSW;
1040
1041   case XED_IFORM_CLTS:
1042     return V3_OP_CLTS;
1043
1044   case XED_IFORM_INVLPG_MEMb:
1045     return V3_OP_INVLPG;
1046
1047
1048     /* Data Instructions */
1049
1050   case XED_IFORM_ADC_MEMv_GPRv:
1051   case XED_IFORM_ADC_MEMv_IMM:
1052   case XED_IFORM_ADC_MEMb_GPR8:
1053   case XED_IFORM_ADC_MEMb_IMM:
1054     return V3_OP_ADC;
1055
1056   case XED_IFORM_ADD_MEMv_GPRv:
1057   case XED_IFORM_ADD_MEMb_IMM:
1058   case XED_IFORM_ADD_MEMb_GPR8:
1059   case XED_IFORM_ADD_MEMv_IMM:
1060     return V3_OP_ADD;
1061
1062   case XED_IFORM_AND_MEMv_IMM:
1063   case XED_IFORM_AND_MEMb_GPR8:
1064   case XED_IFORM_AND_MEMv_GPRv:
1065   case XED_IFORM_AND_MEMb_IMM:
1066     return V3_OP_AND;
1067
1068   case XED_IFORM_SUB_MEMv_IMM:
1069   case XED_IFORM_SUB_MEMb_GPR8:
1070   case XED_IFORM_SUB_MEMb_IMM:
1071   case XED_IFORM_SUB_MEMv_GPRv:
1072     return V3_OP_SUB;
1073
1074   case XED_IFORM_MOV_MEMv_GPRv:
1075   case XED_IFORM_MOV_MEMb_GPR8:
1076   case XED_IFORM_MOV_MEMb_AL:
1077   case XED_IFORM_MOV_MEMv_IMM:
1078   case XED_IFORM_MOV_MEMb_IMM:
1079     return V3_OP_MOV;
1080
1081   case XED_IFORM_DEC_MEMv:
1082   case XED_IFORM_DEC_MEMb:
1083     return V3_OP_DEC;
1084
1085   case XED_IFORM_INC_MEMb:
1086   case XED_IFORM_INC_MEMv:
1087     return V3_OP_INC;
1088
1089   case XED_IFORM_OR_MEMv_IMM:
1090   case XED_IFORM_OR_MEMb_IMM:
1091   case XED_IFORM_OR_MEMv_GPRv:
1092   case XED_IFORM_OR_MEMb_GPR8:
1093     return V3_OP_OR;
1094
1095   case XED_IFORM_XOR_MEMv_GPRv:
1096   case XED_IFORM_XOR_MEMb_IMM:
1097   case XED_IFORM_XOR_MEMb_GPR8:
1098   case XED_IFORM_XOR_MEMv_IMM:
1099     return V3_OP_XOR;
1100
1101   case XED_IFORM_NEG_MEMb:
1102   case XED_IFORM_NEG_MEMv:
1103     return V3_OP_NEG;
1104
1105   case XED_IFORM_NOT_MEMv:
1106   case XED_IFORM_NOT_MEMb:
1107     return V3_OP_NOT;
1108
1109   case XED_IFORM_XCHG_MEMv_GPRv:
1110   case XED_IFORM_XCHG_MEMb_GPR8:
1111     return V3_OP_XCHG;
1112
1113   case XED_IFORM_SETB_MEMb:
1114     return V3_OP_SETB;
1115
1116   case XED_IFORM_SETBE_MEMb:
1117     return V3_OP_SETBE;
1118
1119   case XED_IFORM_SETL_MEMb:
1120     return V3_OP_SETL;
1121
1122   case XED_IFORM_SETLE_MEMb:
1123     return V3_OP_SETLE;
1124
1125   case XED_IFORM_SETNB_MEMb:
1126     return V3_OP_SETNB;
1127
1128   case XED_IFORM_SETNBE_MEMb:
1129     return V3_OP_SETNBE;
1130
1131   case XED_IFORM_SETNL_MEMb:
1132     return V3_OP_SETNL;
1133
1134   case XED_IFORM_SETNLE_MEMb:
1135     return V3_OP_SETNLE;
1136
1137   case XED_IFORM_SETNO_MEMb:
1138     return V3_OP_SETNO;
1139     
1140   case XED_IFORM_SETNP_MEMb:
1141     return V3_OP_SETNP;
1142
1143   case XED_IFORM_SETNS_MEMb:
1144     return V3_OP_SETNS;
1145
1146   case XED_IFORM_SETNZ_MEMb:
1147     return V3_OP_SETNZ;
1148
1149   case XED_IFORM_SETO_MEMb:
1150     return V3_OP_SETO;
1151     
1152   case XED_IFORM_SETP_MEMb:
1153     return V3_OP_SETP;
1154
1155   case XED_IFORM_SETS_MEMb:
1156     return V3_OP_SETS;
1157
1158   case XED_IFORM_SETZ_MEMb:
1159     return V3_OP_SETZ;
1160
1161
1162   case XED_IFORM_MOVSB:
1163   case XED_IFORM_MOVSW:
1164   case XED_IFORM_MOVSD:
1165   case XED_IFORM_MOVSQ:
1166     return V3_OP_MOVS;
1167
1168   default:
1169     return V3_INVALID_OP;
1170   }
1171 }