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.


Resource control extensions to host OS interface
[palacios.releases.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(core->vm_info, core, "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(core->vm_info, core, "\t decoded as (%s)\n", op_form_to_str(form));
106
107     if (form == INVALID_INSTR) {
108         PrintError(core->vm_info, core, "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(core->vm_info, core, "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(core->vm_info, core, "Decoding Instr at %p\n", (void *)core->rip);
126     v3_print_instr(instr);
127     V3_Print(core->vm_info, core, "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(core->vm_info, core, "\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(core->vm_info, core, "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(core->vm_info, core, "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(core->vm_info, core, "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(core->vm_info, core, "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 MOV_MEM2AL_8:
271         case MOV_MEM2AX: {
272
273             /* Use AX for destination operand */
274             instr->dst_operand.size = operand_width;
275             instr->dst_operand.type = REG_OPERAND;
276             instr->dst_operand.operand = (addr_t)&(core->vm_regs.rax);
277             instr->dst_operand.write = 1;
278
279             /* Get the correct offset -- (seg + offset) */
280             struct v3_segment * src_reg = get_instr_segment(core, instr);
281             addr_t offset = 0;
282
283             if (addr_width == 2) {
284                 offset = *(uint16_t *)instr_ptr;
285             } else if (addr_width == 4) {
286                 offset = *(uint32_t *)instr_ptr;
287             } else if (addr_width == 8) {
288                 offset = *(uint64_t *)instr_ptr;
289             } else {
290                 PrintError(core->vm_info, core, "illegal address width for %s (width=%d)\n", 
291                            op_form_to_str(form), addr_width);
292                 return -1;
293             }
294
295             instr->src_operand.operand = ADDR_MASK(get_addr_linear(core, offset, src_reg),
296                                                    get_addr_width(core, instr));
297             
298             instr->src_operand.read = 1;
299             instr->src_operand.type = MEM_OPERAND;
300             instr->src_operand.size = addr_width;
301
302             instr_ptr += addr_width;
303             instr->num_operands = 2;
304             
305             break;
306         }
307         case MOV_AL2MEM_8:
308         case MOV_AX2MEM: {
309
310             /* Use AX for src operand */
311             instr->src_operand.size = operand_width;
312             instr->src_operand.type = REG_OPERAND;
313             instr->src_operand.operand = (addr_t)&(core->vm_regs.rax);
314             instr->src_operand.write = 1;
315
316             /* Get the correct offset -- (seg + offset) */
317             struct v3_segment * dst_reg = get_instr_segment(core, instr);
318             addr_t offset = 0;
319
320             if (addr_width == 2) {
321                 offset = *(uint16_t *)instr_ptr;
322             } else if (addr_width == 4) {
323                 offset = *(uint32_t *)instr_ptr;
324             } else if (addr_width == 8) {
325                 offset = *(uint64_t *)instr_ptr;
326             } else {
327                 PrintError(core->vm_info, core, "illegal address width for %s (width=%d)\n", 
328                            op_form_to_str(form), addr_width);
329                 return -1;
330             }
331
332             instr->dst_operand.operand = ADDR_MASK(get_addr_linear(core, offset, dst_reg),
333                                                    get_addr_width(core, instr));
334             
335             instr->dst_operand.read = 1;
336             instr->dst_operand.type = MEM_OPERAND;
337             instr->dst_operand.size = addr_width;
338
339             instr_ptr += addr_width;
340             instr->num_operands = 2;
341             
342             break;
343         }
344         case MOVSX_8:
345         case MOVZX_8: {
346             uint8_t reg_code = 0;
347
348             ret = decode_rm_operand(core, instr_ptr, form, instr, &(instr->src_operand), &reg_code);
349             instr->src_operand.size = 1;
350
351             if (ret == -1) {
352                 PrintError(core->vm_info, core, "Error decoding operand\n");
353                 return -1;
354             }
355
356             instr_ptr += ret;
357
358             instr->dst_operand.size = operand_width;
359             instr->dst_operand.type = REG_OPERAND;
360             decode_gpr(core, reg_code, &(instr->dst_operand));
361
362             instr->src_operand.read = 1;
363             instr->dst_operand.write = 1;
364
365             instr->num_operands = 2;
366
367             break;
368         }
369         case MOVSX:
370         case MOVZX: {
371             uint8_t reg_code = 0;
372
373             ret = decode_rm_operand(core, instr_ptr, form, instr, &(instr->src_operand), &reg_code);
374             instr->src_operand.size = 2;
375
376             if (ret == -1) {
377                 PrintError(core->vm_info, core, "Error decoding operand\n");
378                 return -1;
379             }
380
381             instr_ptr += ret;
382
383             instr->dst_operand.size = operand_width;
384             instr->dst_operand.type = REG_OPERAND;
385             decode_gpr(core, reg_code, &(instr->dst_operand));
386
387             instr->src_operand.read = 1;
388             instr->dst_operand.write = 1;
389
390             instr->num_operands = 2;
391
392             break;
393         }
394         case ADC_IMM2SX_8:
395         case ADD_IMM2SX_8:
396         case AND_IMM2SX_8:
397         case OR_IMM2SX_8:
398         case SUB_IMM2SX_8:
399         case XOR_IMM2SX_8: {
400             uint8_t reg_code = 0;
401
402             ret = decode_rm_operand(core, instr_ptr, form, instr, &(instr->dst_operand), &reg_code);
403
404             if (ret == -1) {
405                 PrintError(core->vm_info, core, "Error decoding operand\n");
406                 return -1;
407             }
408
409             instr_ptr += ret;
410
411             instr->src_operand.type = IMM_OPERAND;
412             instr->src_operand.size = operand_width;
413             instr->src_operand.operand = (addr_t)MASK((sint64_t)*(sint8_t *)instr_ptr, operand_width);  // sign extend.
414
415             instr->src_operand.read = 1;
416             instr->dst_operand.write = 1;
417
418             instr_ptr += 1;
419
420             instr->num_operands = 2;
421
422             break;
423         }
424         case MOVS:
425         case MOVS_8: {
426             instr->is_str_op = 1;
427             
428             if (instr->prefixes.rep == 1) {
429                 instr->str_op_length = MASK(core->vm_regs.rcx, addr_width);
430             } else {
431                 instr->str_op_length = 1;
432             }
433
434             // Source: DS:(E)SI
435             // Destination: ES:(E)DI
436
437             instr->src_operand.type = MEM_OPERAND;
438             instr->src_operand.size = operand_width;
439             instr->src_operand.operand = get_addr_linear(core,  MASK(core->vm_regs.rsi, addr_width), &(core->segments.ds));
440
441
442             instr->dst_operand.type = MEM_OPERAND;
443             instr->dst_operand.size = operand_width;
444             instr->dst_operand.operand = get_addr_linear(core, MASK(core->vm_regs.rdi, addr_width), &(core->segments.es));
445
446
447             instr->src_operand.read = 1;
448             instr->dst_operand.write = 1;
449
450             instr->num_operands = 2;
451
452             break;
453         }
454         case MOV_2CR: {
455             uint8_t reg_code = 0;
456             
457             ret = decode_rm_operand(core, instr_ptr, form, instr, &(instr->src_operand),
458                                     &reg_code);
459
460             if (ret == -1) {
461                 PrintError(core->vm_info, core, "Error decoding operand for (%s)\n", op_form_to_str(form));
462                 return -1;
463             }
464                 
465             instr_ptr += ret;
466
467             instr->dst_operand.type = REG_OPERAND;
468             instr->dst_operand.size = operand_width;
469             decode_cr(core, reg_code, &(instr->dst_operand));
470             
471             instr->src_operand.read = 1;
472             instr->dst_operand.write = 1;
473
474             instr->num_operands = 2;
475             break;
476         }
477         case MOV_CR2: {
478             uint8_t reg_code = 0;
479             
480             ret = decode_rm_operand(core, instr_ptr, form, instr, &(instr->dst_operand),
481                                     &reg_code);
482             
483             if (ret == -1) {
484                 PrintError(core->vm_info, core, "Error decoding operand for (%s)\n", op_form_to_str(form));
485                 return -1;
486             }
487
488             instr_ptr += ret;
489             
490             instr->src_operand.type = REG_OPERAND;
491             instr->src_operand.size = operand_width;
492             decode_cr(core, reg_code, &(instr->src_operand));
493
494             instr->src_operand.read = 1;
495             instr->dst_operand.write = 1;
496
497             instr->num_operands = 2;
498             break;
499         }
500         case STOS:
501         case STOS_8: {
502             instr->is_str_op = 1;
503
504             if (instr->prefixes.rep == 1) {
505                 instr->str_op_length = MASK(core->vm_regs.rcx, addr_width);
506             } else {
507                 instr->str_op_length = 1;
508             }
509
510             instr->src_operand.size = operand_width;
511             instr->src_operand.type = REG_OPERAND;
512             instr->src_operand.operand = (addr_t)&(core->vm_regs.rax);
513
514             instr->dst_operand.type = MEM_OPERAND;
515             instr->dst_operand.size = operand_width;
516             instr->dst_operand.operand = get_addr_linear(core, MASK(core->vm_regs.rdi, addr_width), &(core->segments.es));
517
518             instr->src_operand.read = 1;
519             instr->dst_operand.write = 1;
520
521             instr->num_operands = 2;
522
523             break;
524         }
525         case INT: {
526             instr->dst_operand.type = IMM_OPERAND;
527             instr->dst_operand.size = operand_width;
528                 instr->dst_operand.operand = *(uint8_t *)instr_ptr;
529             instr_ptr += operand_width;
530             instr->num_operands = 1;
531
532             break;
533         }
534         case INVLPG: {
535             uint8_t reg_code = 0;
536
537             ret = decode_rm_operand(core, instr_ptr, form, instr, &(instr->dst_operand), &reg_code);
538
539             if (ret == -1) {
540                 PrintError(core->vm_info, core, "Error decoding operand for (%s)\n", op_form_to_str(form));
541                 return -1;
542             }
543
544             instr_ptr += ret;
545
546             instr->num_operands = 1;
547             break;
548         }
549         case LMSW: 
550         case SMSW: {
551             uint8_t reg_code = 0;
552
553             ret = decode_rm_operand(core, instr_ptr, form, instr, &(instr->dst_operand), &reg_code);
554
555             if (ret == -1) {
556                 PrintError(core->vm_info, core, "Error decoding operand for (%s)\n", op_form_to_str(form));
557                 return -1;
558             }
559
560             instr_ptr += ret;
561
562             instr->dst_operand.read = 1;
563
564             instr->num_operands = 1;
565             break;
566         }
567         case CLTS: {
568             // no operands. 
569             break;
570         }
571         default:
572             PrintError(core->vm_info, core, "Invalid Instruction form: %s\n", op_form_to_str(form));
573             return -1;
574     }
575
576     return (instr_ptr - instr_start);
577 }
578
579
580 static v3_op_type_t op_form_to_type(op_form_t form) { 
581     switch (form) {
582         case LMSW:
583             return V3_OP_LMSW;
584         case SMSW:
585             return V3_OP_SMSW;
586         case CLTS:
587             return V3_OP_CLTS;
588         case INVLPG:
589             return V3_OP_INVLPG;
590
591         case INT:
592             return V3_OP_INT;
593             
594         case MOV_CR2:
595             return V3_OP_MOVCR2;
596         case MOV_2CR:
597             return V3_OP_MOV2CR;
598
599         case MOV_MEM2_8:
600         case MOV_MEM2:
601         case MOV_2MEM_8:
602         case MOV_2MEM:
603         case MOV_MEM2AL_8:
604         case MOV_MEM2AX:
605         case MOV_AL2MEM_8:
606         case MOV_AX2MEM:
607         case MOV_IMM2_8:
608         case MOV_IMM2:
609             return V3_OP_MOV;
610
611         case MOVS_8:
612         case MOVS:
613             return V3_OP_MOVS;
614
615         case MOVSX_8:
616         case MOVSX:
617             return V3_OP_MOVSX;
618
619         case MOVZX_8:
620         case MOVZX:
621             return V3_OP_MOVZX;
622
623
624         case ADC_2MEM_8:
625         case ADC_2MEM:
626         case ADC_MEM2_8:
627         case ADC_MEM2:
628         case ADC_IMM2_8:
629         case ADC_IMM2:
630         case ADC_IMM2SX_8:
631             return V3_OP_ADC;
632
633
634         case ADD_2MEM_8:
635         case ADD_2MEM:
636         case ADD_MEM2_8:
637         case ADD_MEM2:
638         case ADD_IMM2_8:
639         case ADD_IMM2:
640         case ADD_IMM2SX_8:
641             return V3_OP_ADD;
642
643         case AND_MEM2_8:
644         case AND_MEM2:
645         case AND_2MEM_8:
646         case AND_2MEM:
647         case AND_IMM2_8:
648         case AND_IMM2:
649         case AND_IMM2SX_8:
650             return V3_OP_AND;
651
652         case OR_2MEM_8:
653         case OR_2MEM:
654         case OR_MEM2_8:
655         case OR_MEM2:
656         case OR_IMM2_8:
657         case OR_IMM2:
658         case OR_IMM2SX_8:
659             return V3_OP_OR;
660
661         case SUB_2MEM_8:
662         case SUB_2MEM:
663         case SUB_MEM2_8:
664         case SUB_MEM2:
665         case SUB_IMM2_8:
666         case SUB_IMM2:
667         case SUB_IMM2SX_8:
668             return V3_OP_SUB;
669
670         case XOR_2MEM_8:
671         case XOR_2MEM:
672         case XOR_MEM2_8:
673         case XOR_MEM2:
674         case XOR_IMM2_8:
675         case XOR_IMM2:
676         case XOR_IMM2SX_8:
677             return V3_OP_XOR;
678
679         case INC_8:
680         case INC:
681             return V3_OP_INC;
682
683         case DEC_8:
684         case DEC:
685             return V3_OP_DEC;
686
687         case NEG_8:
688         case NEG: 
689             return V3_OP_NEG;
690
691         case NOT_8:
692         case NOT:
693             return V3_OP_NOT;
694
695         case XCHG_8:
696         case XCHG:
697             return V3_OP_XCHG;
698             
699         case SETB:
700             return V3_OP_SETB;
701         case SETBE:
702             return V3_OP_SETBE;
703         case SETL:
704             return V3_OP_SETL;
705         case SETLE:
706             return V3_OP_SETLE;
707         case SETNB:
708             return V3_OP_SETNB;
709         case SETNBE:
710             return V3_OP_SETNBE;
711         case SETNL:
712             return V3_OP_SETNL;
713         case SETNLE:
714             return V3_OP_SETNLE;
715         case SETNO:
716             return V3_OP_SETNO;
717         case SETNP:
718             return V3_OP_SETNP;
719         case SETNS:
720             return V3_OP_SETNS;
721         case SETNZ:
722             return V3_OP_SETNZ;
723         case SETP:
724             return V3_OP_SETP;
725         case SETS:
726             return V3_OP_SETS;
727         case SETZ:
728             return V3_OP_SETZ;
729         case SETO:
730             return V3_OP_SETO;
731             
732         case STOS_8:
733         case STOS:
734             return V3_OP_STOS;
735
736         case HLT:
737         case PUSHF:
738         case POPF:
739         case MOV_DR2:
740         case MOV_2DR:
741         case MOV_SR2:
742         case MOV_2SR:
743
744         default:
745             return V3_INVALID_OP;
746
747     }
748 }