Palacios Public Git Repository

To checkout Palacios execute

  git clone http://v3vee.org/palacios/palacios.web/palacios.git
This will give you the master branch. You probably want the devel branch or one of the release branches. To switch to the devel branch, simply execute
  cd palacios
  git checkout --track -b devel origin/devel
The other branches are similar.


added support for register instrs
[palacios.git] / palacios / src / palacios / vmm_xed.c
1 #include <palacios/vmm_decoder.h>
2 #include <palacios/vmm_xed.h>
3 #include <xed/xed-interface.h>
4 #include <palacios/vm_guest.h>
5
6 static xed_state_t decoder_state;
7
8
9
10 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);
11
12
13 static int set_decoder_mode(struct guest_info * info, xed_state_t * state) {
14   switch (info->cpu_mode) {
15   case REAL:
16     if (state->mmode != XED_MACHINE_MODE_LEGACY_16) {
17       xed_state_init(state,
18                      XED_MACHINE_MODE_LEGACY_16, 
19                      XED_ADDRESS_WIDTH_16b, 
20                      XED_ADDRESS_WIDTH_16b); 
21     }
22    break;
23   case PROTECTED:
24   case PROTECTED_PAE:
25     if (state->mmode != XED_MACHINE_MODE_LEGACY_32) {
26       xed_state_init(state,
27                      XED_MACHINE_MODE_LEGACY_32, 
28                      XED_ADDRESS_WIDTH_32b, 
29                      XED_ADDRESS_WIDTH_32b);
30     }
31     break;
32   case LONG:
33     if (state->mmode != XED_MACHINE_MODE_LONG_64) {    
34       state->mmode = XED_MACHINE_MODE_LONG_64;
35     }
36     break;
37   default:
38     return -1;
39   }
40   return 0;
41 }
42
43
44
45
46
47 int init_decoder() {
48   xed_tables_init();
49   xed_state_zero(&decoder_state);
50   return 0;
51 }
52
53
54 int v3_decode(struct guest_info * info, addr_t instr_ptr, struct x86_instr * instr) {
55   xed_decoded_inst_t xed_instr;
56   xed_error_enum_t xed_error;
57
58
59
60   if (set_decoder_mode(info, &decoder_state) == -1) {
61     PrintError("Could not set decoder mode\n");
62     return -1;
63   }
64
65
66
67   xed_decoded_inst_zero_set_mode(&xed_instr, &decoder_state);
68
69
70   
71
72   xed_error = xed_decode(&xed_instr, 
73                          REINTERPRET_CAST(const xed_uint8_t *, instr_ptr), 
74                          XED_MAX_INSTRUCTION_BYTES);
75   
76
77
78
79
80
81   if (xed_error != XED_ERROR_NONE) {
82     PrintError("Xed error: %s\n", xed_error_enum_t2str(xed_error));
83     return -1;
84   }
85
86   const xed_inst_t * xi = xed_decoded_inst_inst(&xed_instr);
87   
88   instr->instr_length = xed_decoded_inst_get_length(&xed_instr);
89   instr->num_operands = xed_decoded_inst_noperands(&xed_instr);
90
91
92   PrintDebug("Number of operands: %d\n", instr->num_operands);
93
94   // set first operand
95   if (instr->num_operands >= 1) {
96     const xed_operand_t * op = xed_inst_operand(xi, 0);
97     xed_operand_type_enum_t op_type = xed_operand_type(op);
98     xed_operand_enum_t op_enum = xed_operand_name(op);
99
100
101     if (xed_operand_is_register(op_enum)) {
102       xed_reg_enum_t xed_reg =  xed_decoded_inst_get_reg(&xed_instr, op_enum);
103       if (xed_reg_to_v3_reg(info, 
104                             xed_reg, 
105                             &(instr->dst_operand.operand), 
106                             &(instr->dst_operand.size)) == -1) {
107         
108         PrintError("First operand is an Unhandled Operand: %s\n", xed_reg_enum_t2str(xed_reg));
109         return -1;
110       }
111
112       PrintDebug("xed_reg=0x%x, cr0=0x%x\n", instr->dst_operand.operand, &(info->ctrl_regs.cr0));
113
114     } else {
115       PrintError("Unhandled first operand type %s\n", xed_operand_type_enum_t2str(op_type));
116       return -1;
117     }
118   }
119
120   // set second operand
121   if (instr->num_operands >= 2) {
122     const xed_operand_t * op = xed_inst_operand(xi, 1);
123     xed_operand_type_enum_t op_type = xed_operand_type(op);
124     xed_operand_enum_t op_enum = xed_operand_name(op);
125     
126     if (xed_operand_is_register(op_enum)) {
127       xed_reg_enum_t xed_reg =  xed_decoded_inst_get_reg(&xed_instr, op_enum);
128       if (xed_reg_to_v3_reg(info, 
129                             xed_reg, 
130                             &(instr->src_operand.operand), 
131                             &(instr->src_operand.size)) == -1) {
132         
133         PrintError("Second operand is an Unhandled Operand: %s\n", xed_reg_enum_t2str(xed_reg));
134         return -1;
135       }
136       PrintDebug("xed_reg=0x%x, eax=0x%x\n", instr->src_operand.operand, &(info->vm_regs.rax));
137       
138     } else {
139       PrintError("Unhandled second operand type %s\n", xed_operand_type_enum_t2str(op_type));
140       return -1;
141     }
142   }
143
144   // set third operand
145   if (instr->num_operands >= 3) {
146     const xed_operand_t * op = xed_inst_operand(xi, 2);
147     xed_operand_type_enum_t op_type = xed_operand_type(op);
148     xed_operand_enum_t op_enum = xed_operand_name(op);
149
150     if (xed_operand_is_register(op_enum)) {
151       xed_reg_enum_t xed_reg =  xed_decoded_inst_get_reg(&xed_instr, op_enum);
152       if (xed_reg_to_v3_reg(info, 
153                             xed_reg, 
154                             &(instr->extra_operand.operand), 
155                             &(instr->extra_operand.size)) == -1) {
156         
157         PrintError("Third operand is an Unhandled Operand: %s\n", xed_reg_enum_t2str(xed_reg));
158         return -1;
159       }
160     } else {
161       PrintError("Unhandled third operand type %s\n", xed_operand_type_enum_t2str(op_type));
162       return -1;
163     }
164
165
166   }
167
168   /*
169     PrintDebug("category: %s\n", xed_category_enum_t2str(xed_decoded_inst_get_category(&xed_instr)));;
170     PrintDebug("ISA-extension:%s\n ",xed_extension_enum_t2str(xed_decoded_inst_get_extension(&xed_instr)));
171     PrintDebug(" instruction-length: %d\n ", xed_decoded_inst_get_length(&xed_instr));
172     PrintDebug(" operand-size:%d\n ", xed_operand_values_get_effective_operand_width(xed_decoded_inst_operands_const(&xed_instr)));   
173     PrintDebug("address-size:%d\n ", xed_operand_values_get_effective_address_width(xed_decoded_inst_operands_const(&xed_instr))); 
174     PrintDebug("iform-enum-name:%s\n ",xed_iform_enum_t2str(xed_decoded_inst_get_iform_enum(&xed_instr)));
175     PrintDebug("iform-enum-name-dispatch (zero based):%d\n ", xed_decoded_inst_get_iform_enum_dispatch(&xed_instr));
176     PrintDebug("iclass-max-iform-dispatch: %d\n ", xed_iform_max_per_iclass(xed_decoded_inst_get_iclass(&xed_instr)));
177   */  
178   // operands
179   // print_operands(&xed_instr);
180   
181   // memops
182   // print_memops(&xed_instr);
183   
184   // flags
185   //print_flags(&xed_instr);
186   
187   // attributes
188   //print_attributes(&xed_instr);*/
189
190
191
192     return -1;
193 }
194
195
196 int v3_encode(struct guest_info * info, struct x86_instr * instr, char * instr_buf) {
197
198   return -1;
199 }
200
201
202 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) {
203
204   switch (xed_reg) {
205   case XED_REG_INVALID:
206     *v3_reg = 0;
207     *reg_len = 0;
208     return -1;
209
210     /* 
211      * GPRs
212      */
213   case XED_REG_RAX: 
214     *v3_reg = (addr_t)&(info->vm_regs.rax);
215     *reg_len = 8;
216     break;
217   case XED_REG_EAX:
218     *v3_reg = (addr_t)&(info->vm_regs.rax);
219     *reg_len = 4;
220     break;
221   case XED_REG_AX:
222     *v3_reg = (addr_t)&(info->vm_regs.rax);
223     *reg_len = 2;
224     break;
225   case XED_REG_AH:
226     *v3_reg = (addr_t)(&(info->vm_regs.rax)) + 1;
227     *reg_len = 1;
228     break;
229   case XED_REG_AL:
230     *v3_reg = (addr_t)&(info->vm_regs.rax);
231     *reg_len = 1;
232     break;
233
234   case XED_REG_RCX: 
235     *v3_reg = (addr_t)&(info->vm_regs.rcx);
236     *reg_len = 8;
237     break;
238   case XED_REG_ECX:
239     *v3_reg = (addr_t)&(info->vm_regs.rcx);
240     *reg_len = 4;
241     break;
242   case XED_REG_CX:
243     *v3_reg = (addr_t)&(info->vm_regs.rcx);
244     *reg_len = 2;
245     break;
246   case XED_REG_CH:
247     *v3_reg = (addr_t)(&(info->vm_regs.rcx)) + 1;
248     *reg_len = 1;
249     break;
250   case XED_REG_CL:
251     *v3_reg = (addr_t)&(info->vm_regs.rcx);
252     *reg_len = 1;
253     break;
254
255   case XED_REG_RDX: 
256     *v3_reg = (addr_t)&(info->vm_regs.rdx);
257     *reg_len = 8;
258     break;
259   case XED_REG_EDX:
260     *v3_reg = (addr_t)&(info->vm_regs.rdx);
261     *reg_len = 4;
262     break;
263   case XED_REG_DX:
264     *v3_reg = (addr_t)&(info->vm_regs.rdx);
265     *reg_len = 2;
266     break;
267   case XED_REG_DH:
268     *v3_reg = (addr_t)(&(info->vm_regs.rdx)) + 1;
269     *reg_len = 1;
270     break;
271   case XED_REG_DL:
272     *v3_reg = (addr_t)&(info->vm_regs.rdx);
273     *reg_len = 1;
274     break;
275
276   case XED_REG_RBX: 
277     *v3_reg = (addr_t)&(info->vm_regs.rbx);
278     *reg_len = 8;
279     break;
280   case XED_REG_EBX:
281     *v3_reg = (addr_t)&(info->vm_regs.rbx);
282     *reg_len = 4;
283     break;
284   case XED_REG_BX:
285     *v3_reg = (addr_t)&(info->vm_regs.rbx);
286     *reg_len = 2;
287     break;
288   case XED_REG_BH:
289     *v3_reg = (addr_t)(&(info->vm_regs.rbx)) + 1;
290     *reg_len = 1;
291     break;
292   case XED_REG_BL:
293     *v3_reg = (addr_t)&(info->vm_regs.rbx);
294     *reg_len = 1;
295     break;
296
297
298   case XED_REG_RSP:
299     *v3_reg = (addr_t)&(info->vm_regs.rsp);
300     *reg_len = 8;
301     break;
302   case XED_REG_ESP:
303     *v3_reg = (addr_t)&(info->vm_regs.rsp);
304     *reg_len = 4;
305     break;
306   case XED_REG_SP:
307     *v3_reg = (addr_t)&(info->vm_regs.rsp);
308     *reg_len = 2;
309     break;
310   case XED_REG_SPL:
311     *v3_reg = (addr_t)&(info->vm_regs.rsp);
312     *reg_len = 1;
313     break;
314
315   case XED_REG_RBP:
316     *v3_reg = (addr_t)&(info->vm_regs.rbp);
317     *reg_len = 8;
318     break;
319   case XED_REG_EBP:
320     *v3_reg = (addr_t)&(info->vm_regs.rbp);
321     *reg_len = 4;
322     break;
323   case XED_REG_BP:
324     *v3_reg = (addr_t)&(info->vm_regs.rbp);
325     *reg_len = 2;
326     break;
327   case XED_REG_BPL:
328     *v3_reg = (addr_t)&(info->vm_regs.rbp);
329     *reg_len = 1;
330     break;
331
332
333
334   case XED_REG_RSI:
335     *v3_reg = (addr_t)&(info->vm_regs.rsi);
336     *reg_len = 8;
337     break;
338   case XED_REG_ESI:
339     *v3_reg = (addr_t)&(info->vm_regs.rsi);
340     *reg_len = 4;
341     break;
342   case XED_REG_SI:
343     *v3_reg = (addr_t)&(info->vm_regs.rsi);
344     *reg_len = 2;
345     break;
346   case XED_REG_SIL:
347     *v3_reg = (addr_t)&(info->vm_regs.rsi);
348     *reg_len = 1;
349     break;
350
351
352   case XED_REG_RDI:
353     *v3_reg = (addr_t)&(info->vm_regs.rdi);
354     *reg_len = 8;
355     break;
356   case XED_REG_EDI:
357     *v3_reg = (addr_t)&(info->vm_regs.rdi);
358     *reg_len = 4;
359     break;
360   case XED_REG_DI:
361     *v3_reg = (addr_t)&(info->vm_regs.rdi);
362     *reg_len = 2;
363     break;
364   case XED_REG_DIL:
365     *v3_reg = (addr_t)&(info->vm_regs.rdi);
366     *reg_len = 1;
367     break;
368
369
370     /* 
371      *  CTRL REGS
372      */
373   case XED_REG_RIP:
374     *v3_reg = (addr_t)&(info->rip);
375     *reg_len = 8;
376     break;
377   case XED_REG_EIP:
378     *v3_reg = (addr_t)&(info->rip);
379     *reg_len = 4;
380     break;  
381   case XED_REG_IP:
382     *v3_reg = (addr_t)&(info->rip);
383     *reg_len = 2;
384     break;
385
386   case XED_REG_FLAGS:
387     *v3_reg = (addr_t)&(info->ctrl_regs.rflags);
388     *reg_len = 2;
389     break;
390   case XED_REG_EFLAGS:
391     *v3_reg = (addr_t)&(info->ctrl_regs.rflags);
392     *reg_len = 4;
393     break;
394   case XED_REG_RFLAGS:
395     *v3_reg = (addr_t)&(info->ctrl_regs.rflags);
396     *reg_len = 8;
397     break;
398
399   case XED_REG_CR0:
400     *v3_reg = (addr_t)&(info->ctrl_regs.cr0);
401     *reg_len = 4;
402     break;
403   case XED_REG_CR2:
404     *v3_reg = (addr_t)&(info->ctrl_regs.cr2);
405     *reg_len = 4;
406     break;
407   case XED_REG_CR3:
408     *v3_reg = (addr_t)&(info->ctrl_regs.cr3);
409     *reg_len = 4;
410     break;
411   case XED_REG_CR4:
412     *v3_reg = (addr_t)&(info->ctrl_regs.cr4);
413     *reg_len = 4;
414     break;
415   case XED_REG_CR8:
416     *v3_reg = (addr_t)&(info->ctrl_regs.cr8);
417     *reg_len = 4;
418     break;
419
420   case XED_REG_CR1:
421   case XED_REG_CR5:
422   case XED_REG_CR6:
423   case XED_REG_CR7:
424   case XED_REG_CR9:
425   case XED_REG_CR10:
426   case XED_REG_CR11:
427   case XED_REG_CR12:
428   case XED_REG_CR13:
429   case XED_REG_CR14:
430   case XED_REG_CR15:
431     return -1;
432
433
434
435
436     /* 
437      * SEGMENT REGS
438      */
439   case XED_REG_CS:
440     *v3_reg = (addr_t)&(info->segments.cs.selector);
441     *reg_len = 16;
442     break;
443   case XED_REG_DS:
444     *v3_reg = (addr_t)&(info->segments.ds.selector);
445     *reg_len = 16;
446     break;
447   case XED_REG_ES:
448     *v3_reg = (addr_t)&(info->segments.es.selector);
449     *reg_len = 16;
450     break;
451   case XED_REG_SS:
452     *v3_reg = (addr_t)&(info->segments.ss.selector);
453     *reg_len = 16;
454     break;
455   case XED_REG_FS:
456     *v3_reg = (addr_t)&(info->segments.fs.selector);
457     *reg_len = 16;
458     break;
459   case XED_REG_GS:
460     *v3_reg = (addr_t)&(info->segments.fs.selector);
461     *reg_len = 16;
462     break;
463
464
465   case XED_REG_GDTR:
466   case XED_REG_LDTR:
467   case XED_REG_IDTR:
468   case XED_REG_TR:
469     PrintError("Segment selector operand... Don't know how to handle this...\n");
470     return -1;
471
472     /* 
473      *  DEBUG REGS
474      */
475   case XED_REG_DR0:
476   case XED_REG_DR1:
477   case XED_REG_DR2:
478   case XED_REG_DR3:
479   case XED_REG_DR4:
480   case XED_REG_DR5:
481   case XED_REG_DR6:
482   case XED_REG_DR7:
483   case XED_REG_DR8:
484   case XED_REG_DR9:
485   case XED_REG_DR10:
486   case XED_REG_DR11:
487   case XED_REG_DR12:
488   case XED_REG_DR13:
489   case XED_REG_DR14:
490   case XED_REG_DR15:
491     return -1;
492
493
494
495
496   case XED_REG_R8:
497   case XED_REG_R8D:
498   case XED_REG_R8W:
499   case XED_REG_R8B:
500
501   case XED_REG_R9:
502   case XED_REG_R9D:
503   case XED_REG_R9W:
504   case XED_REG_R9B:
505
506   case XED_REG_R10:
507   case XED_REG_R10D:
508   case XED_REG_R10W:
509   case XED_REG_R10B:
510
511   case XED_REG_R11:
512   case XED_REG_R11D:
513   case XED_REG_R11W:
514   case XED_REG_R11B:
515
516   case XED_REG_R12:
517   case XED_REG_R12D:
518   case XED_REG_R12W:
519   case XED_REG_R12B:
520
521   case XED_REG_R13:
522   case XED_REG_R13D:
523   case XED_REG_R13W:
524   case XED_REG_R13B:
525
526   case XED_REG_R14:
527   case XED_REG_R14D:
528   case XED_REG_R14W:
529   case XED_REG_R14B:
530
531   case XED_REG_R15:
532   case XED_REG_R15D:
533   case XED_REG_R15W:
534   case XED_REG_R15B:
535
536   case XED_REG_XMM0:
537   case XED_REG_XMM1:
538   case XED_REG_XMM2:
539   case XED_REG_XMM3:
540   case XED_REG_XMM4:
541   case XED_REG_XMM5:
542   case XED_REG_XMM6:
543   case XED_REG_XMM7:
544   case XED_REG_XMM8:
545   case XED_REG_XMM9:
546   case XED_REG_XMM10:
547   case XED_REG_XMM11:
548   case XED_REG_XMM12:
549   case XED_REG_XMM13:
550   case XED_REG_XMM14:
551   case XED_REG_XMM15:
552
553   case XED_REG_MMX0:
554   case XED_REG_MMX1:
555   case XED_REG_MMX2:
556   case XED_REG_MMX3:
557   case XED_REG_MMX4:
558   case XED_REG_MMX5:
559   case XED_REG_MMX6:
560   case XED_REG_MMX7:
561
562   case XED_REG_ST0:
563   case XED_REG_ST1:
564   case XED_REG_ST2:
565   case XED_REG_ST3:
566   case XED_REG_ST4:
567   case XED_REG_ST5:
568   case XED_REG_ST6:
569   case XED_REG_ST7:
570
571   case XED_REG_ONE:
572   case XED_REG_STACKPUSH:
573   case XED_REG_STACKPOP:
574     
575   case XED_REG_TSC:
576   case XED_REG_TSCAUX:
577   case XED_REG_MSRS:
578
579   case XED_REG_X87CONTROL:
580   case XED_REG_X87STATUS:
581   case XED_REG_X87TOP:
582   case XED_REG_X87TAG:
583   case XED_REG_X87PUSH:
584   case XED_REG_X87POP:
585   case XED_REG_X87POP2:
586
587   case XED_REG_MXCSR:
588
589   case XED_REG_TMP0:
590   case XED_REG_TMP1:
591   case XED_REG_TMP2:
592   case XED_REG_TMP3:
593   case XED_REG_TMP4:
594   case XED_REG_TMP5:
595   case XED_REG_TMP6:
596   case XED_REG_TMP7:
597   case XED_REG_TMP8:
598   case XED_REG_TMP9:
599   case XED_REG_TMP10:
600   case XED_REG_TMP11:
601   case XED_REG_TMP12:
602   case XED_REG_TMP13:
603   case XED_REG_TMP14:
604   case XED_REG_TMP15:
605
606   case XED_REG_LAST:
607
608   case XED_REG_ERROR:
609     // error??
610     return -1;
611
612   }
613
614
615   return 0;
616 }