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.


Previous software interrupt support was added to Xed, but I wasn't using the kernel
[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("Decoding Instr at %p\n", (void *)core->rip);
126     v3_print_instr(instr);
127     V3_Print("CS DB FLag=%x\n", core->segments.cs.db);
128 #endif
129
130     return 0;
131 }
132
133
134 static int parse_operands(struct guest_info * core, uint8_t * instr_ptr, 
135                           struct x86_instr * instr, op_form_t form) {
136     // get operational mode of the guest for operand width
137     uint8_t operand_width = get_operand_width(core, instr, form);
138     uint8_t addr_width = get_addr_width(core, instr);
139     int ret = 0;
140     uint8_t * instr_start = instr_ptr;
141     
142
143     PrintDebug("\tOperand width=%d, Addr width=%d\n", operand_width, addr_width);
144
145     switch (form) {
146         case ADC_IMM2_8:
147         case ADD_IMM2_8:
148         case AND_IMM2_8:
149         case OR_IMM2_8:
150         case SUB_IMM2_8:
151         case XOR_IMM2_8:
152         case MOV_IMM2_8:
153         case ADC_IMM2:
154         case ADD_IMM2:
155         case AND_IMM2:  
156         case OR_IMM2:
157         case SUB_IMM2:
158         case XOR_IMM2:
159         case MOV_IMM2: {
160             uint8_t reg_code = 0;
161
162             ret = decode_rm_operand(core, instr_ptr, form, instr, &(instr->dst_operand), &reg_code);
163
164             if (ret == -1) {
165                 PrintError("Error decoding operand\n");
166                 return -1;
167             }
168
169             instr_ptr += ret;
170
171             instr->src_operand.type = IMM_OPERAND;
172             instr->src_operand.size = operand_width;
173
174
175             if (operand_width == 1) {
176                 instr->src_operand.operand = *(uint8_t *)instr_ptr;
177             } else if (operand_width == 2) {
178                 instr->src_operand.operand = *(uint16_t *)instr_ptr;
179             } else if (operand_width == 4) {
180                 instr->src_operand.operand = *(uint32_t *)instr_ptr;
181             } else if (operand_width == 8) {
182                 instr->src_operand.operand = *(sint32_t *)instr_ptr; // This is a special case for sign extended 64bit ops
183             } else {
184                 PrintError("Illegal operand width (%d)\n", operand_width);
185                 return -1;
186             }
187
188             instr->src_operand.read = 1;
189             instr->dst_operand.write = 1;
190
191             instr_ptr += operand_width;
192
193             instr->num_operands = 2;
194
195             break;
196         }
197         case ADC_2MEM_8:
198         case ADD_2MEM_8:
199         case AND_2MEM_8:
200         case OR_2MEM_8:
201         case SUB_2MEM_8:
202         case XOR_2MEM_8:
203         case MOV_2MEM_8:
204         case ADC_2MEM:
205         case ADD_2MEM:
206         case AND_2MEM:
207         case OR_2MEM:
208         case SUB_2MEM:
209         case XOR_2MEM:
210         case MOV_2MEM: {
211             uint8_t reg_code = 0;
212
213             ret = decode_rm_operand(core, instr_ptr, form, instr, &(instr->dst_operand), &reg_code);
214
215             if (ret == -1) {
216                 PrintError("Error decoding operand\n");
217                 return -1;
218             }
219
220             instr_ptr += ret;
221
222             instr->src_operand.type = REG_OPERAND;
223             instr->src_operand.size = operand_width;
224
225             instr->src_operand.read = 1;
226             instr->dst_operand.write = 1;
227
228
229             decode_gpr(core, reg_code, &(instr->src_operand));
230
231             instr->num_operands = 2;
232             break;
233         }
234         case ADC_MEM2_8:
235         case ADD_MEM2_8:
236         case AND_MEM2_8:
237         case OR_MEM2_8:
238         case SUB_MEM2_8:
239         case XOR_MEM2_8:
240         case MOV_MEM2_8:
241         case ADC_MEM2:
242         case ADD_MEM2:
243         case AND_MEM2:
244         case OR_MEM2:
245         case SUB_MEM2:
246         case XOR_MEM2:
247         case MOV_MEM2: {
248             uint8_t reg_code = 0;
249
250             ret = decode_rm_operand(core, instr_ptr, form, instr, &(instr->src_operand), &reg_code);
251
252             if (ret == -1) {
253                 PrintError("Error decoding operand\n");
254                 return -1;
255             }
256
257             instr_ptr += ret;
258
259             instr->dst_operand.size = operand_width;
260             instr->dst_operand.type = REG_OPERAND;
261             decode_gpr(core, reg_code, &(instr->dst_operand));
262
263             instr->src_operand.read = 1;
264             instr->dst_operand.write = 1;
265
266             instr->num_operands = 2;
267
268             break;
269         }
270         case MOVSX_8:
271         case MOVZX_8: {
272             uint8_t reg_code = 0;
273
274             ret = decode_rm_operand(core, instr_ptr, form, instr, &(instr->src_operand), &reg_code);
275             instr->src_operand.size = 1;
276
277             if (ret == -1) {
278                 PrintError("Error decoding operand\n");
279                 return -1;
280             }
281
282             instr_ptr += ret;
283
284             instr->dst_operand.size = operand_width;
285             instr->dst_operand.type = REG_OPERAND;
286             decode_gpr(core, reg_code, &(instr->dst_operand));
287
288             instr->src_operand.read = 1;
289             instr->dst_operand.write = 1;
290
291             instr->num_operands = 2;
292
293             break;
294         }
295         case MOVSX:
296         case MOVZX: {
297             uint8_t reg_code = 0;
298
299             ret = decode_rm_operand(core, instr_ptr, form, instr, &(instr->src_operand), &reg_code);
300             instr->src_operand.size = 2;
301
302             if (ret == -1) {
303                 PrintError("Error decoding operand\n");
304                 return -1;
305             }
306
307             instr_ptr += ret;
308
309             instr->dst_operand.size = operand_width;
310             instr->dst_operand.type = REG_OPERAND;
311             decode_gpr(core, reg_code, &(instr->dst_operand));
312
313             instr->src_operand.read = 1;
314             instr->dst_operand.write = 1;
315
316             instr->num_operands = 2;
317
318             break;
319         }
320         case ADC_IMM2SX_8:
321         case ADD_IMM2SX_8:
322         case AND_IMM2SX_8:
323         case OR_IMM2SX_8:
324         case SUB_IMM2SX_8:
325         case XOR_IMM2SX_8: {
326             uint8_t reg_code = 0;
327
328             ret = decode_rm_operand(core, instr_ptr, form, instr, &(instr->dst_operand), &reg_code);
329
330             if (ret == -1) {
331                 PrintError("Error decoding operand\n");
332                 return -1;
333             }
334
335             instr_ptr += ret;
336
337             instr->src_operand.type = IMM_OPERAND;
338             instr->src_operand.size = operand_width;
339             instr->src_operand.operand = (addr_t)MASK((sint64_t)*(sint8_t *)instr_ptr, operand_width);  // sign extend.
340
341             instr->src_operand.read = 1;
342             instr->dst_operand.write = 1;
343
344             instr_ptr += 1;
345
346             instr->num_operands = 2;
347
348             break;
349         }
350         case MOVS:
351         case MOVS_8: {
352             instr->is_str_op = 1;
353             
354             if (instr->prefixes.rep == 1) {
355                 instr->str_op_length = MASK(core->vm_regs.rcx, addr_width);
356             } else {
357                 instr->str_op_length = 1;
358             }
359
360             // Source: DS:(E)SI
361             // Destination: ES:(E)DI
362
363             instr->src_operand.type = MEM_OPERAND;
364             instr->src_operand.size = operand_width;
365             instr->src_operand.operand = get_addr_linear(core,  MASK(core->vm_regs.rsi, addr_width), &(core->segments.ds));
366
367
368             instr->dst_operand.type = MEM_OPERAND;
369             instr->dst_operand.size = operand_width;
370             instr->dst_operand.operand = get_addr_linear(core, MASK(core->vm_regs.rdi, addr_width), &(core->segments.es));
371
372
373             instr->src_operand.read = 1;
374             instr->dst_operand.write = 1;
375
376             instr->num_operands = 2;
377
378             break;
379         }
380         case MOV_2CR: {
381             uint8_t reg_code = 0;
382             
383             ret = decode_rm_operand(core, instr_ptr, form, instr, &(instr->src_operand),
384                                     &reg_code);
385
386             if (ret == -1) {
387                 PrintError("Error decoding operand for (%s)\n", op_form_to_str(form));
388                 return -1;
389             }
390                 
391             instr_ptr += ret;
392
393             instr->dst_operand.type = REG_OPERAND;
394             instr->dst_operand.size = operand_width;
395             decode_cr(core, reg_code, &(instr->dst_operand));
396             
397             instr->src_operand.read = 1;
398             instr->dst_operand.write = 1;
399
400             instr->num_operands = 2;
401             break;
402         }
403         case MOV_CR2: {
404             uint8_t reg_code = 0;
405             
406             ret = decode_rm_operand(core, instr_ptr, form, instr, &(instr->dst_operand),
407                                     &reg_code);
408             
409             if (ret == -1) {
410                 PrintError("Error decoding operand for (%s)\n", op_form_to_str(form));
411                 return -1;
412             }
413
414             instr_ptr += ret;
415             
416             instr->src_operand.type = REG_OPERAND;
417             instr->src_operand.size = operand_width;
418             decode_cr(core, reg_code, &(instr->src_operand));
419
420             instr->src_operand.read = 1;
421             instr->dst_operand.write = 1;
422
423             instr->num_operands = 2;
424             break;
425         }
426         case STOS:
427         case STOS_8: {
428             instr->is_str_op = 1;
429
430             if (instr->prefixes.rep == 1) {
431                 instr->str_op_length = MASK(core->vm_regs.rcx, addr_width);
432             } else {
433                 instr->str_op_length = 1;
434             }
435
436             instr->src_operand.size = operand_width;
437             instr->src_operand.type = REG_OPERAND;
438             instr->src_operand.operand = (addr_t)&(core->vm_regs.rax);
439
440             instr->dst_operand.type = MEM_OPERAND;
441             instr->dst_operand.size = operand_width;
442             instr->dst_operand.operand = get_addr_linear(core, MASK(core->vm_regs.rdi, addr_width), &(core->segments.es));
443
444             instr->src_operand.read = 1;
445             instr->dst_operand.write = 1;
446
447             instr->num_operands = 2;
448
449             break;
450         }
451         case INT: {
452             instr->dst_operand.type = IMM_OPERAND;
453             instr->dst_operand.size = operand_width;
454                 instr->dst_operand.operand = *(uint8_t *)instr_ptr;
455             instr_ptr += operand_width;
456             instr->num_operands = 1;
457
458             break;
459         }
460         case INVLPG: {
461             uint8_t reg_code = 0;
462
463             ret = decode_rm_operand(core, instr_ptr, form, instr, &(instr->dst_operand), &reg_code);
464
465             if (ret == -1) {
466                 PrintError("Error decoding operand for (%s)\n", op_form_to_str(form));
467                 return -1;
468             }
469
470             instr_ptr += ret;
471
472             instr->num_operands = 1;
473             break;
474         }
475         case LMSW: 
476         case SMSW: {
477             uint8_t reg_code = 0;
478
479             ret = decode_rm_operand(core, instr_ptr, form, instr, &(instr->dst_operand), &reg_code);
480
481             if (ret == -1) {
482                 PrintError("Error decoding operand for (%s)\n", op_form_to_str(form));
483                 return -1;
484             }
485
486             instr_ptr += ret;
487
488             instr->dst_operand.read = 1;
489
490             instr->num_operands = 1;
491             break;
492         }
493         case CLTS: {
494             // no operands. 
495             break;
496         }
497         default:
498             PrintError("Invalid Instruction form: %s\n", op_form_to_str(form));
499             return -1;
500     }
501
502     return (instr_ptr - instr_start);
503 }
504
505
506 static v3_op_type_t op_form_to_type(op_form_t form) { 
507     switch (form) {
508         case LMSW:
509             return V3_OP_LMSW;
510         case SMSW:
511             return V3_OP_SMSW;
512         case CLTS:
513             return V3_OP_CLTS;
514         case INVLPG:
515             return V3_OP_INVLPG;
516
517         case INT:
518             return V3_OP_INT;
519             
520         case MOV_CR2:
521             return V3_OP_MOVCR2;
522         case MOV_2CR:
523             return V3_OP_MOV2CR;
524
525         case MOV_MEM2_8:
526         case MOV_MEM2:
527         case MOV_2MEM_8:
528         case MOV_2MEM:
529         case MOV_MEM2AL_8:
530         case MOV_MEM2AX:
531         case MOV_AL2MEM_8:
532         case MOV_AX2MEM:
533         case MOV_IMM2_8:
534         case MOV_IMM2:
535             return V3_OP_MOV;
536
537         case MOVS_8:
538         case MOVS:
539             return V3_OP_MOVS;
540
541         case MOVSX_8:
542         case MOVSX:
543             return V3_OP_MOVSX;
544
545         case MOVZX_8:
546         case MOVZX:
547             return V3_OP_MOVZX;
548
549
550         case ADC_2MEM_8:
551         case ADC_2MEM:
552         case ADC_MEM2_8:
553         case ADC_MEM2:
554         case ADC_IMM2_8:
555         case ADC_IMM2:
556         case ADC_IMM2SX_8:
557             return V3_OP_ADC;
558
559
560         case ADD_2MEM_8:
561         case ADD_2MEM:
562         case ADD_MEM2_8:
563         case ADD_MEM2:
564         case ADD_IMM2_8:
565         case ADD_IMM2:
566         case ADD_IMM2SX_8:
567             return V3_OP_ADD;
568
569         case AND_MEM2_8:
570         case AND_MEM2:
571         case AND_2MEM_8:
572         case AND_2MEM:
573         case AND_IMM2_8:
574         case AND_IMM2:
575         case AND_IMM2SX_8:
576             return V3_OP_AND;
577
578         case OR_2MEM_8:
579         case OR_2MEM:
580         case OR_MEM2_8:
581         case OR_MEM2:
582         case OR_IMM2_8:
583         case OR_IMM2:
584         case OR_IMM2SX_8:
585             return V3_OP_OR;
586
587         case SUB_2MEM_8:
588         case SUB_2MEM:
589         case SUB_MEM2_8:
590         case SUB_MEM2:
591         case SUB_IMM2_8:
592         case SUB_IMM2:
593         case SUB_IMM2SX_8:
594             return V3_OP_SUB;
595
596         case XOR_2MEM_8:
597         case XOR_2MEM:
598         case XOR_MEM2_8:
599         case XOR_MEM2:
600         case XOR_IMM2_8:
601         case XOR_IMM2:
602         case XOR_IMM2SX_8:
603             return V3_OP_XOR;
604
605         case INC_8:
606         case INC:
607             return V3_OP_INC;
608
609         case DEC_8:
610         case DEC:
611             return V3_OP_DEC;
612
613         case NEG_8:
614         case NEG: 
615             return V3_OP_NEG;
616
617         case NOT_8:
618         case NOT:
619             return V3_OP_NOT;
620
621         case XCHG_8:
622         case XCHG:
623             return V3_OP_XCHG;
624             
625         case SETB:
626             return V3_OP_SETB;
627         case SETBE:
628             return V3_OP_SETBE;
629         case SETL:
630             return V3_OP_SETL;
631         case SETLE:
632             return V3_OP_SETLE;
633         case SETNB:
634             return V3_OP_SETNB;
635         case SETNBE:
636             return V3_OP_SETNBE;
637         case SETNL:
638             return V3_OP_SETNL;
639         case SETNLE:
640             return V3_OP_SETNLE;
641         case SETNO:
642             return V3_OP_SETNO;
643         case SETNP:
644             return V3_OP_SETNP;
645         case SETNS:
646             return V3_OP_SETNS;
647         case SETNZ:
648             return V3_OP_SETNZ;
649         case SETP:
650             return V3_OP_SETP;
651         case SETS:
652             return V3_OP_SETS;
653         case SETZ:
654             return V3_OP_SETZ;
655         case SETO:
656             return V3_OP_SETO;
657             
658         case STOS_8:
659         case STOS:
660             return V3_OP_STOS;
661
662         case HLT:
663         case PUSHF:
664         case POPF:
665         case MOV_DR2:
666         case MOV_2DR:
667         case MOV_SR2:
668         case MOV_2SR:
669
670         default:
671             return V3_INVALID_OP;
672
673     }
674 }