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.


5980dcbc7cbce9f8d8436dd604fb39472a7cfb98
[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 INVLPG: {
452             uint8_t reg_code = 0;
453
454             ret = decode_rm_operand(core, instr_ptr, form, instr, &(instr->dst_operand), &reg_code);
455
456             if (ret == -1) {
457                 PrintError("Error decoding operand for (%s)\n", op_form_to_str(form));
458                 return -1;
459             }
460
461             instr_ptr += ret;
462
463             instr->num_operands = 1;
464             break;
465         }
466         case LMSW: 
467         case SMSW: {
468             uint8_t reg_code = 0;
469
470             ret = decode_rm_operand(core, instr_ptr, form, instr, &(instr->dst_operand), &reg_code);
471
472             if (ret == -1) {
473                 PrintError("Error decoding operand for (%s)\n", op_form_to_str(form));
474                 return -1;
475             }
476
477             instr_ptr += ret;
478
479             instr->dst_operand.read = 1;
480
481             instr->num_operands = 1;
482             break;
483         }
484         case CLTS: {
485             // no operands. 
486             break;
487         }
488         default:
489             PrintError("Invalid Instruction form: %s\n", op_form_to_str(form));
490             return -1;
491     }
492
493     return (instr_ptr - instr_start);
494 }
495
496
497 static v3_op_type_t op_form_to_type(op_form_t form) { 
498     switch (form) {
499         case LMSW:
500             return V3_OP_LMSW;
501         case SMSW:
502             return V3_OP_SMSW;
503         case CLTS:
504             return V3_OP_CLTS;
505         case INVLPG:
506             return V3_OP_INVLPG;
507
508         case INT:
509             return V3_OP_INT;
510             
511         case MOV_CR2:
512             return V3_OP_MOVCR2;
513         case MOV_2CR:
514             return V3_OP_MOV2CR;
515
516         case MOV_MEM2_8:
517         case MOV_MEM2:
518         case MOV_2MEM_8:
519         case MOV_2MEM:
520         case MOV_MEM2AL_8:
521         case MOV_MEM2AX:
522         case MOV_AL2MEM_8:
523         case MOV_AX2MEM:
524         case MOV_IMM2_8:
525         case MOV_IMM2:
526             return V3_OP_MOV;
527
528         case MOVS_8:
529         case MOVS:
530             return V3_OP_MOVS;
531
532         case MOVSX_8:
533         case MOVSX:
534             return V3_OP_MOVSX;
535
536         case MOVZX_8:
537         case MOVZX:
538             return V3_OP_MOVZX;
539
540
541         case ADC_2MEM_8:
542         case ADC_2MEM:
543         case ADC_MEM2_8:
544         case ADC_MEM2:
545         case ADC_IMM2_8:
546         case ADC_IMM2:
547         case ADC_IMM2SX_8:
548             return V3_OP_ADC;
549
550
551         case ADD_2MEM_8:
552         case ADD_2MEM:
553         case ADD_MEM2_8:
554         case ADD_MEM2:
555         case ADD_IMM2_8:
556         case ADD_IMM2:
557         case ADD_IMM2SX_8:
558             return V3_OP_ADD;
559
560         case AND_MEM2_8:
561         case AND_MEM2:
562         case AND_2MEM_8:
563         case AND_2MEM:
564         case AND_IMM2_8:
565         case AND_IMM2:
566         case AND_IMM2SX_8:
567             return V3_OP_AND;
568
569         case OR_2MEM_8:
570         case OR_2MEM:
571         case OR_MEM2_8:
572         case OR_MEM2:
573         case OR_IMM2_8:
574         case OR_IMM2:
575         case OR_IMM2SX_8:
576             return V3_OP_OR;
577
578         case SUB_2MEM_8:
579         case SUB_2MEM:
580         case SUB_MEM2_8:
581         case SUB_MEM2:
582         case SUB_IMM2_8:
583         case SUB_IMM2:
584         case SUB_IMM2SX_8:
585             return V3_OP_SUB;
586
587         case XOR_2MEM_8:
588         case XOR_2MEM:
589         case XOR_MEM2_8:
590         case XOR_MEM2:
591         case XOR_IMM2_8:
592         case XOR_IMM2:
593         case XOR_IMM2SX_8:
594             return V3_OP_XOR;
595
596         case INC_8:
597         case INC:
598             return V3_OP_INC;
599
600         case DEC_8:
601         case DEC:
602             return V3_OP_DEC;
603
604         case NEG_8:
605         case NEG: 
606             return V3_OP_NEG;
607
608         case NOT_8:
609         case NOT:
610             return V3_OP_NOT;
611
612         case XCHG_8:
613         case XCHG:
614             return V3_OP_XCHG;
615             
616         case SETB:
617             return V3_OP_SETB;
618         case SETBE:
619             return V3_OP_SETBE;
620         case SETL:
621             return V3_OP_SETL;
622         case SETLE:
623             return V3_OP_SETLE;
624         case SETNB:
625             return V3_OP_SETNB;
626         case SETNBE:
627             return V3_OP_SETNBE;
628         case SETNL:
629             return V3_OP_SETNL;
630         case SETNLE:
631             return V3_OP_SETNLE;
632         case SETNO:
633             return V3_OP_SETNO;
634         case SETNP:
635             return V3_OP_SETNP;
636         case SETNS:
637             return V3_OP_SETNS;
638         case SETNZ:
639             return V3_OP_SETNZ;
640         case SETP:
641             return V3_OP_SETP;
642         case SETS:
643             return V3_OP_SETS;
644         case SETZ:
645             return V3_OP_SETZ;
646         case SETO:
647             return V3_OP_SETO;
648             
649         case STOS_8:
650         case STOS:
651             return V3_OP_STOS;
652
653         case HLT:
654         case PUSHF:
655         case POPF:
656         case MOV_DR2:
657         case MOV_2DR:
658         case MOV_SR2:
659         case MOV_2SR:
660
661         default:
662             return V3_INVALID_OP;
663
664     }
665 }