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.


Software interrupt decoder support
[palacios.git] / palacios / src / palacios / vmm_v3dec.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 #include <palacios/vmm_decoder.h>
21 #include <palacios/vmm_instr_decoder.h>
22
23 #ifndef V3_CONFIG_DEBUG_DECODER
24 #undef PrintDebug
25 #define PrintDebug(fmt, args...)
26 #endif
27
28
29 #define MASK(val, length) ({                                            \
30             uint64_t mask = 0x0LL;                                      \
31             switch (length) {                                           \
32                 case 1:                                                 \
33                     mask = 0x00000000000000ffLL;                        \
34                     break;                                              \
35                 case 2:                                                 \
36                     mask = 0x000000000000ffffLL;                        \
37                     break;                                              \
38                 case 4:                                                 \
39                     mask = 0x00000000ffffffffLL;                        \
40                     break;                                              \
41                 case 8:                                                 \
42                     mask = 0xffffffffffffffffLL;                        \
43                     break;                                              \
44             }                                                           \
45             val & mask;                                                 \
46         })
47
48 static v3_op_type_t op_form_to_type(op_form_t form);
49 static int parse_operands(struct guest_info * core, uint8_t * instr_ptr, struct x86_instr * instr, op_form_t form);
50
51
52 int v3_disasm(struct guest_info * info, void *instr_ptr, addr_t * rip, int mark) {
53     return -1;
54 }
55
56
57 int v3_init_decoder(struct guest_info * core) { 
58     return 0;
59 }
60
61
62 int v3_deinit_decoder(struct guest_info * core) {
63     return 0;
64 }
65
66
67 int v3_encode(struct guest_info * info, struct x86_instr * instr, uint8_t * instr_buf) {
68     return -1;
69 }
70
71
72 int v3_decode(struct guest_info * core, addr_t instr_ptr, struct x86_instr * instr) {
73     op_form_t form = INVALID_INSTR; 
74     int ret = 0;
75     int length = 0;
76
77
78     PrintDebug("Decoding Instruction at %p\n", (void *)instr_ptr);
79
80     memset(instr, 0, sizeof(struct x86_instr));
81
82     // scan for prefixes
83     length = v3_get_prefixes((uint8_t *)instr_ptr, &(instr->prefixes));
84
85
86     // REX prefix
87     if (v3_get_vm_cpu_mode(core) == LONG) {
88         uint8_t prefix = *(uint8_t *)(instr_ptr + length);
89
90         if ((prefix & 0xf0) == 0x40) {
91             instr->prefixes.rex = 1;
92
93             instr->prefixes.rex_rm = (prefix & 0x01);
94             instr->prefixes.rex_sib_idx = ((prefix & 0x02) >> 1);
95             instr->prefixes.rex_reg = ((prefix & 0x04) >> 2);
96             instr->prefixes.rex_op_size = ((prefix & 0x08) >> 3);
97
98             length += 1;
99         }
100     }
101
102
103     form = op_code_to_form((uint8_t *)(instr_ptr + length), &length);
104
105     PrintDebug("\t decoded as (%s)\n", op_form_to_str(form));
106
107     if (form == INVALID_INSTR) {
108         PrintError("Could not find instruction form (%x)\n", *(uint32_t *)(instr_ptr + length));
109         return -1;
110     }
111
112     instr->op_type = op_form_to_type(form);
113
114     ret = parse_operands(core, (uint8_t *)(instr_ptr + length), instr, form);
115
116     if (ret == -1) {
117         PrintError("Could not parse instruction operands\n");
118         return -1;
119     }
120     length += ret;
121
122     instr->instr_length += length;
123
124 #ifdef V3_CONFIG_DEBUG_DECODER
125     v3_print_instr(instr);
126 #endif
127
128     return 0;
129 }
130
131
132 static int parse_operands(struct guest_info * core, uint8_t * instr_ptr, 
133                           struct x86_instr * instr, op_form_t form) {
134     // get operational mode of the guest for operand width
135     uint8_t operand_width = get_operand_width(core, instr, form);
136     uint8_t addr_width = get_addr_width(core, instr);
137     int ret = 0;
138     uint8_t * instr_start = instr_ptr;
139     
140
141     PrintDebug("\tOperand width=%d, Addr width=%d\n", operand_width, addr_width);
142
143     switch (form) {
144         case ADC_IMM2_8:
145         case ADD_IMM2_8:
146         case AND_IMM2_8:
147         case OR_IMM2_8:
148         case SUB_IMM2_8:
149         case XOR_IMM2_8:
150         case MOV_IMM2_8:
151         case ADC_IMM2:
152         case ADD_IMM2:
153         case AND_IMM2:  
154         case OR_IMM2:
155         case SUB_IMM2:
156         case XOR_IMM2: 
157         case MOV_IMM2:{
158             uint8_t reg_code = 0;
159
160             ret = decode_rm_operand(core, instr_ptr, form, instr, &(instr->dst_operand), &reg_code);
161
162             if (ret == -1) {
163                 PrintError("Error decoding operand\n");
164                 return -1;
165             }
166
167             instr_ptr += ret;
168
169             instr->src_operand.type = IMM_OPERAND;
170             instr->src_operand.size = operand_width;
171
172
173             if (operand_width == 1) {
174                 instr->src_operand.operand = *(uint8_t *)instr_ptr;
175             } else if (operand_width == 2) {
176                 instr->src_operand.operand = *(uint16_t *)instr_ptr;
177             } else if (operand_width == 4) {
178                 instr->src_operand.operand = *(uint32_t *)instr_ptr;
179             } else {
180                 PrintError("Illegal operand width (%d)\n", operand_width);
181                 return -1;
182             }
183
184             instr->src_operand.read = 1;
185             instr->dst_operand.write = 1;
186
187             instr_ptr += operand_width;
188
189             instr->num_operands = 2;
190
191             break;
192         }
193         case ADC_2MEM_8:
194         case ADD_2MEM_8:
195         case AND_2MEM_8:
196         case OR_2MEM_8:
197         case SUB_2MEM_8:
198         case XOR_2MEM_8:
199         case MOV_2MEM_8:
200         case ADC_2MEM:
201         case ADD_2MEM:
202         case AND_2MEM:
203         case OR_2MEM:
204         case SUB_2MEM:
205         case XOR_2MEM:
206         case MOV_2MEM: {
207             uint8_t reg_code = 0;
208
209             ret = decode_rm_operand(core, instr_ptr, form, instr, &(instr->dst_operand), &reg_code);
210
211             if (ret == -1) {
212                 PrintError("Error decoding operand\n");
213                 return -1;
214             }
215
216             instr_ptr += ret;
217
218             instr->src_operand.type = REG_OPERAND;
219             instr->src_operand.size = operand_width;
220
221             instr->src_operand.read = 1;
222             instr->dst_operand.write = 1;
223
224
225             decode_gpr(core, reg_code, &(instr->src_operand));
226
227             instr->num_operands = 2;
228             break;
229         }
230         case ADC_MEM2_8:
231         case ADD_MEM2_8:
232         case AND_MEM2_8:
233         case OR_MEM2_8:
234         case SUB_MEM2_8:
235         case XOR_MEM2_8:
236         case MOV_MEM2_8:
237         case ADC_MEM2:
238         case ADD_MEM2:
239         case AND_MEM2:
240         case OR_MEM2:
241         case SUB_MEM2:
242         case XOR_MEM2:
243         case MOV_MEM2: {
244             uint8_t reg_code = 0;
245
246             ret = decode_rm_operand(core, instr_ptr, form, instr, &(instr->src_operand), &reg_code);
247
248             if (ret == -1) {
249                 PrintError("Error decoding operand\n");
250                 return -1;
251             }
252
253             instr_ptr += ret;
254
255             instr->dst_operand.size = operand_width;
256             instr->dst_operand.type = REG_OPERAND;
257             decode_gpr(core, reg_code, &(instr->dst_operand));
258
259             instr->src_operand.read = 1;
260             instr->dst_operand.write = 1;
261
262             instr->num_operands = 2;
263
264             break;
265         }
266         case MOVSX_8:
267         case MOVZX_8: {
268             uint8_t reg_code = 0;
269
270             ret = decode_rm_operand(core, instr_ptr, form, instr, &(instr->src_operand), &reg_code);
271             instr->src_operand.size = 1;
272
273             if (ret == -1) {
274                 PrintError("Error decoding operand\n");
275                 return -1;
276             }
277
278             instr_ptr += ret;
279
280             instr->dst_operand.size = operand_width;
281             instr->dst_operand.type = REG_OPERAND;
282             decode_gpr(core, reg_code, &(instr->dst_operand));
283
284             instr->src_operand.read = 1;
285             instr->dst_operand.write = 1;
286
287             instr->num_operands = 2;
288
289             break;
290         }
291         case MOVSX:
292         case MOVZX: {
293             uint8_t reg_code = 0;
294
295             ret = decode_rm_operand(core, instr_ptr, form, instr, &(instr->src_operand), &reg_code);
296             instr->src_operand.size = 2;
297
298             if (ret == -1) {
299                 PrintError("Error decoding operand\n");
300                 return -1;
301             }
302
303             instr_ptr += ret;
304
305             instr->dst_operand.size = operand_width;
306             instr->dst_operand.type = REG_OPERAND;
307             decode_gpr(core, reg_code, &(instr->dst_operand));
308
309             instr->src_operand.read = 1;
310             instr->dst_operand.write = 1;
311
312             instr->num_operands = 2;
313
314             break;
315         }
316         case ADC_IMM2SX_8:
317         case ADD_IMM2SX_8:
318         case AND_IMM2SX_8:
319         case OR_IMM2SX_8:
320         case SUB_IMM2SX_8:
321         case XOR_IMM2SX_8: {
322             uint8_t reg_code = 0;
323
324             ret = decode_rm_operand(core, instr_ptr, form, instr, &(instr->dst_operand), &reg_code);
325
326             if (ret == -1) {
327                 PrintError("Error decoding operand\n");
328                 return -1;
329             }
330
331             instr_ptr += ret;
332
333             instr->src_operand.type = IMM_OPERAND;
334             instr->src_operand.size = operand_width;
335             instr->src_operand.operand = (addr_t)MASK((sint64_t)*(sint8_t *)instr_ptr, operand_width);  // sign extend.
336
337             instr->src_operand.read = 1;
338             instr->dst_operand.write = 1;
339
340             instr_ptr += 1;
341
342             instr->num_operands = 2;
343
344             break;
345         }
346         case MOVS:
347         case MOVS_8: {
348             instr->is_str_op = 1;
349             
350             if (instr->prefixes.rep == 1) {
351                 instr->str_op_length = MASK(core->vm_regs.rcx, operand_width);
352             } else {
353                 instr->str_op_length = 1;
354             }
355
356             // Source: DS:(E)SI
357             // Destination: ES:(E)DI
358
359             instr->src_operand.type = MEM_OPERAND;
360             instr->src_operand.size = operand_width;
361             instr->src_operand.operand = get_addr_linear(core,  MASK(core->vm_regs.rsi, addr_width), &(core->segments.ds));
362
363
364             instr->dst_operand.type = MEM_OPERAND;
365             instr->dst_operand.size = operand_width;
366             instr->dst_operand.operand = get_addr_linear(core, MASK(core->vm_regs.rdi, addr_width), &(core->segments.es));
367
368
369             instr->src_operand.read = 1;
370             instr->dst_operand.write = 1;
371
372             instr->num_operands = 2;
373
374             break;
375         }
376         case MOV_2CR: {
377             uint8_t reg_code = 0;
378             
379             ret = decode_rm_operand(core, instr_ptr, form, instr, &(instr->src_operand),
380                                     &reg_code);
381
382             if (ret == -1) {
383                 PrintError("Error decoding operand for (%s)\n", op_form_to_str(form));
384                 return -1;
385             }
386                 
387             instr_ptr += ret;
388
389             instr->dst_operand.type = REG_OPERAND;
390             instr->dst_operand.size = operand_width;
391             decode_cr(core, reg_code, &(instr->dst_operand));
392             
393             instr->src_operand.read = 1;
394             instr->dst_operand.write = 1;
395
396             instr->num_operands = 2;
397             break;
398         }
399         case MOV_CR2: {
400             uint8_t reg_code = 0;
401             
402             ret = decode_rm_operand(core, instr_ptr, form, instr, &(instr->dst_operand),
403                                     &reg_code);
404             
405             if (ret == -1) {
406                 PrintError("Error decoding operand for (%s)\n", op_form_to_str(form));
407                 return -1;
408             }
409
410             instr_ptr += ret;
411             
412             instr->src_operand.type = REG_OPERAND;
413             instr->src_operand.size = operand_width;
414             decode_cr(core, reg_code, &(instr->src_operand));
415
416             instr->src_operand.read = 1;
417             instr->dst_operand.write = 1;
418
419             instr->num_operands = 2;
420             break;
421         }
422         case STOS:
423         case STOS_8: {
424             instr->is_str_op = 1;
425
426             if (instr->prefixes.rep == 1) {
427                 instr->str_op_length = MASK(core->vm_regs.rcx, operand_width);
428             } else {
429                 instr->str_op_length = 1;
430             }
431
432             instr->src_operand.size = operand_width;
433             instr->src_operand.type = REG_OPERAND;
434             instr->src_operand.operand = (addr_t)&(core->vm_regs.rax);
435
436             instr->dst_operand.type = MEM_OPERAND;
437             instr->dst_operand.size = operand_width;
438             instr->dst_operand.operand = get_addr_linear(core, MASK(core->vm_regs.rdi, addr_width), &(core->segments.es));
439
440             instr->src_operand.read = 1;
441             instr->dst_operand.write = 1;
442
443             instr->num_operands = 2;
444
445             break;
446         }
447         case INVLPG: {
448             uint8_t reg_code = 0;
449
450             ret = decode_rm_operand(core, instr_ptr, form, instr, &(instr->dst_operand), &reg_code);
451
452             if (ret == -1) {
453                 PrintError("Error decoding operand for (%s)\n", op_form_to_str(form));
454                 return -1;
455             }
456
457             instr_ptr += ret;
458
459             instr->num_operands = 1;
460             break;
461         }
462         case LMSW: 
463         case SMSW: {
464             uint8_t reg_code = 0;
465
466             ret = decode_rm_operand(core, instr_ptr, form, instr, &(instr->dst_operand), &reg_code);
467
468             if (ret == -1) {
469                 PrintError("Error decoding operand for (%s)\n", op_form_to_str(form));
470                 return -1;
471             }
472
473             instr_ptr += ret;
474
475             instr->dst_operand.read = 1;
476
477             instr->num_operands = 1;
478             break;
479         }
480         case CLTS: {
481             // no operands. 
482             break;
483         }
484         default:
485             PrintError("Invalid Instruction form: %s\n", op_form_to_str(form));
486             return -1;
487     }
488
489     return (instr_ptr - instr_start);
490 }
491
492
493 static v3_op_type_t op_form_to_type(op_form_t form) { 
494     switch (form) {
495         case LMSW:
496             return V3_OP_LMSW;
497         case SMSW:
498             return V3_OP_SMSW;
499         case CLTS:
500             return V3_OP_CLTS;
501         case INVLPG:
502             return V3_OP_INVLPG;
503
504         case INT:
505             return V3_OP_INT;
506             
507         case MOV_CR2:
508             return V3_OP_MOVCR2;
509         case MOV_2CR:
510             return V3_OP_MOV2CR;
511
512         case MOV_MEM2_8:
513         case MOV_MEM2:
514         case MOV_2MEM_8:
515         case MOV_2MEM:
516         case MOV_MEM2AL_8:
517         case MOV_MEM2AX:
518         case MOV_AL2MEM_8:
519         case MOV_AX2MEM:
520         case MOV_IMM2_8:
521         case MOV_IMM2:
522             return V3_OP_MOV;
523
524         case MOVS_8:
525         case MOVS:
526             return V3_OP_MOVS;
527
528         case MOVSX_8:
529         case MOVSX:
530             return V3_OP_MOVSX;
531
532         case MOVZX_8:
533         case MOVZX:
534             return V3_OP_MOVZX;
535
536
537         case ADC_2MEM_8:
538         case ADC_2MEM:
539         case ADC_MEM2_8:
540         case ADC_MEM2:
541         case ADC_IMM2_8:
542         case ADC_IMM2:
543         case ADC_IMM2SX_8:
544             return V3_OP_ADC;
545
546
547         case ADD_2MEM_8:
548         case ADD_2MEM:
549         case ADD_MEM2_8:
550         case ADD_MEM2:
551         case ADD_IMM2_8:
552         case ADD_IMM2:
553         case ADD_IMM2SX_8:
554             return V3_OP_ADD;
555
556         case AND_MEM2_8:
557         case AND_MEM2:
558         case AND_2MEM_8:
559         case AND_2MEM:
560         case AND_IMM2_8:
561         case AND_IMM2:
562         case AND_IMM2SX_8:
563             return V3_OP_AND;
564
565         case OR_2MEM_8:
566         case OR_2MEM:
567         case OR_MEM2_8:
568         case OR_MEM2:
569         case OR_IMM2_8:
570         case OR_IMM2:
571         case OR_IMM2SX_8:
572             return V3_OP_OR;
573
574         case SUB_2MEM_8:
575         case SUB_2MEM:
576         case SUB_MEM2_8:
577         case SUB_MEM2:
578         case SUB_IMM2_8:
579         case SUB_IMM2:
580         case SUB_IMM2SX_8:
581             return V3_OP_SUB;
582
583         case XOR_2MEM_8:
584         case XOR_2MEM:
585         case XOR_MEM2_8:
586         case XOR_MEM2:
587         case XOR_IMM2_8:
588         case XOR_IMM2:
589         case XOR_IMM2SX_8:
590             return V3_OP_XOR;
591
592         case INC_8:
593         case INC:
594             return V3_OP_INC;
595
596         case DEC_8:
597         case DEC:
598             return V3_OP_DEC;
599
600         case NEG_8:
601         case NEG: 
602             return V3_OP_NEG;
603
604         case NOT_8:
605         case NOT:
606             return V3_OP_NOT;
607
608         case XCHG_8:
609         case XCHG:
610             return V3_OP_XCHG;
611             
612         case SETB:
613             return V3_OP_SETB;
614         case SETBE:
615             return V3_OP_SETBE;
616         case SETL:
617             return V3_OP_SETL;
618         case SETLE:
619             return V3_OP_SETLE;
620         case SETNB:
621             return V3_OP_SETNB;
622         case SETNBE:
623             return V3_OP_SETNBE;
624         case SETNL:
625             return V3_OP_SETNL;
626         case SETNLE:
627             return V3_OP_SETNLE;
628         case SETNO:
629             return V3_OP_SETNO;
630         case SETNP:
631             return V3_OP_SETNP;
632         case SETNS:
633             return V3_OP_SETNS;
634         case SETNZ:
635             return V3_OP_SETNZ;
636         case SETP:
637             return V3_OP_SETP;
638         case SETS:
639             return V3_OP_SETS;
640         case SETZ:
641             return V3_OP_SETZ;
642         case SETO:
643             return V3_OP_SETO;
644             
645         case STOS_8:
646         case STOS:
647             return V3_OP_STOS;
648
649         case HLT:
650         case PUSHF:
651         case POPF:
652         case MOV_DR2:
653         case MOV_2DR:
654         case MOV_SR2:
655         case MOV_2SR:
656
657         default:
658             return V3_INVALID_OP;
659
660     }
661 }