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.


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