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.


reverted syscall changes
[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 MOV_CR2:
505             return V3_OP_MOVCR2;
506         case MOV_2CR:
507             return V3_OP_MOV2CR;
508
509
510         case MOV_MEM2_8:
511         case MOV_MEM2:
512         case MOV_2MEM_8:
513         case MOV_2MEM:
514         case MOV_MEM2AL_8:
515         case MOV_MEM2AX:
516         case MOV_AL2MEM_8:
517         case MOV_AX2MEM:
518         case MOV_IMM2_8:
519         case MOV_IMM2:
520             return V3_OP_MOV;
521
522         case MOVS_8:
523         case MOVS:
524             return V3_OP_MOVS;
525
526         case MOVSX_8:
527         case MOVSX:
528             return V3_OP_MOVSX;
529
530         case MOVZX_8:
531         case MOVZX:
532             return V3_OP_MOVZX;
533
534
535         case ADC_2MEM_8:
536         case ADC_2MEM:
537         case ADC_MEM2_8:
538         case ADC_MEM2:
539         case ADC_IMM2_8:
540         case ADC_IMM2:
541         case ADC_IMM2SX_8:
542             return V3_OP_ADC;
543
544
545         case ADD_2MEM_8:
546         case ADD_2MEM:
547         case ADD_MEM2_8:
548         case ADD_MEM2:
549         case ADD_IMM2_8:
550         case ADD_IMM2:
551         case ADD_IMM2SX_8:
552             return V3_OP_ADD;
553
554         case AND_MEM2_8:
555         case AND_MEM2:
556         case AND_2MEM_8:
557         case AND_2MEM:
558         case AND_IMM2_8:
559         case AND_IMM2:
560         case AND_IMM2SX_8:
561             return V3_OP_AND;
562
563         case OR_2MEM_8:
564         case OR_2MEM:
565         case OR_MEM2_8:
566         case OR_MEM2:
567         case OR_IMM2_8:
568         case OR_IMM2:
569         case OR_IMM2SX_8:
570             return V3_OP_OR;
571
572         case SUB_2MEM_8:
573         case SUB_2MEM:
574         case SUB_MEM2_8:
575         case SUB_MEM2:
576         case SUB_IMM2_8:
577         case SUB_IMM2:
578         case SUB_IMM2SX_8:
579             return V3_OP_SUB;
580
581         case XOR_2MEM_8:
582         case XOR_2MEM:
583         case XOR_MEM2_8:
584         case XOR_MEM2:
585         case XOR_IMM2_8:
586         case XOR_IMM2:
587         case XOR_IMM2SX_8:
588             return V3_OP_XOR;
589
590         case INC_8:
591         case INC:
592             return V3_OP_INC;
593
594         case DEC_8:
595         case DEC:
596             return V3_OP_DEC;
597
598         case NEG_8:
599         case NEG: 
600             return V3_OP_NEG;
601
602         case NOT_8:
603         case NOT:
604             return V3_OP_NOT;
605
606         case XCHG_8:
607         case XCHG:
608             return V3_OP_XCHG;
609             
610         case SETB:
611             return V3_OP_SETB;
612         case SETBE:
613             return V3_OP_SETBE;
614         case SETL:
615             return V3_OP_SETL;
616         case SETLE:
617             return V3_OP_SETLE;
618         case SETNB:
619             return V3_OP_SETNB;
620         case SETNBE:
621             return V3_OP_SETNBE;
622         case SETNL:
623             return V3_OP_SETNL;
624         case SETNLE:
625             return V3_OP_SETNLE;
626         case SETNO:
627             return V3_OP_SETNO;
628         case SETNP:
629             return V3_OP_SETNP;
630         case SETNS:
631             return V3_OP_SETNS;
632         case SETNZ:
633             return V3_OP_SETNZ;
634         case SETP:
635             return V3_OP_SETP;
636         case SETS:
637             return V3_OP_SETS;
638         case SETZ:
639             return V3_OP_SETZ;
640         case SETO:
641             return V3_OP_SETO;
642             
643         case STOS_8:
644         case STOS:
645             return V3_OP_STOS;
646
647         case HLT:
648         case PUSHF:
649         case POPF:
650         case MOV_DR2:
651         case MOV_2DR:
652         case MOV_SR2:
653         case MOV_2SR:
654
655         default:
656             return V3_INVALID_OP;
657
658     }
659 }