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.


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