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