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.


dd0abd935c367ec70884c82e600005053eb70698
[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
24 #define MASK(val, length) ({                                            \
25             ullong_t mask = 0x0LL;                                      \
26             switch (length) {                                           \
27                 case 1:                                                 \
28                     mask = 0x00000000000000ffLL;                        \
29                     break;                                              \
30                 case 2:                                                 \
31                     mask = 0x000000000000ffffLL;                        \
32                     break;                                              \
33                 case 4:                                                 \
34                     mask = 0x00000000ffffffffLL;                        \
35                     break;                                              \
36                 case 8:                                                 \
37                     mask = 0xffffffffffffffffLL;                        \
38                     break;                                              \
39             }                                                           \
40             val & mask;                                                 \
41         })
42
43 static v3_op_type_t op_form_to_type(op_form_t form);
44 static int parse_operands(struct guest_info * core, uint8_t * instr_ptr, struct x86_instr * instr, op_form_t form);
45
46
47 int v3_disasm(struct guest_info * info, void *instr_ptr, addr_t * rip, int mark) {
48     return -1;
49 }
50
51
52 int v3_init_decoder(struct guest_info * core) { 
53     return 0;
54 }
55
56
57 int v3_deinit_decoder(struct guest_info * core) {
58     return 0;
59 }
60
61
62 int v3_encode(struct guest_info * info, struct x86_instr * instr, uint8_t * instr_buf) {
63     return -1;
64 }
65
66
67 int v3_decode(struct guest_info * core, addr_t instr_ptr, struct x86_instr * instr) {
68     op_form_t form = INVALID_INSTR; 
69     int ret = 0;
70     int length = 0;
71
72
73     V3_Print("Decoding Instruction at %p\n", (void *)instr_ptr);
74
75     memset(instr, 0, sizeof(struct x86_instr));
76
77     // scan for prefixes
78     length = v3_get_prefixes((uint8_t *)instr_ptr, &(instr->prefixes));
79
80
81     // REX prefix
82     if (v3_get_vm_cpu_mode(core) == LONG) {
83         if ((*(uint8_t *)(instr_ptr + length) & 0xf0) == 0x40) {
84             *(uint8_t *)&(instr->prefixes.rex) = *(uint8_t *)(instr_ptr + length);
85             length += 1;
86         }
87     }
88
89
90     form = op_code_to_form((uint8_t *)(instr_ptr + length), &length);
91
92
93     V3_Print("\t decoded as (%s)\n", op_form_to_str(form));
94
95     if (form == INVALID_INSTR) {
96         PrintError("Could not find instruction form (%x)\n", *(uint32_t *)(instr_ptr + length));
97         return -1;
98     }
99
100     instr->op_type = op_form_to_type(form);
101
102     ret = parse_operands(core, (uint8_t *)(instr_ptr + length), instr, form);
103
104     if (ret == -1) {
105         PrintError("Could not parse instruction operands\n");
106         return -1;
107     }
108     length += ret;
109     
110
111     instr->instr_length += length;
112
113
114     v3_print_instr(instr);
115
116     return 0;
117 }
118
119
120 static int parse_operands(struct guest_info * core, uint8_t * instr_ptr, 
121                           struct x86_instr * instr, op_form_t form) {
122     // get operational mode of the guest for operand width
123     uint8_t operand_width = get_operand_width(core, instr, form);
124     uint8_t addr_width = get_addr_width(core, instr);
125     int ret = 0;
126     uint8_t * instr_start = instr_ptr;
127     
128
129     PrintDebug("\tOperand width=%d, Addr width=%d\n", operand_width, addr_width);
130
131     switch (form) {
132         case ADC_IMM2_8:
133         case ADD_IMM2_8:
134         case AND_IMM2_8:
135         case OR_IMM2_8:
136         case SUB_IMM2_8:
137         case XOR_IMM2_8:
138         case MOV_IMM2_8:
139         case ADC_IMM2:
140         case ADD_IMM2:
141         case AND_IMM2:  
142         case OR_IMM2:
143         case SUB_IMM2:
144         case XOR_IMM2: 
145         case MOV_IMM2:{
146             uint8_t reg_code = 0;
147
148             ret = decode_rm_operand(core, instr_ptr, form, instr, &(instr->dst_operand), &reg_code);
149
150             if (ret == -1) {
151                 PrintError("Error decoding operand\n");
152                 return -1;
153             }
154
155             instr_ptr += ret;
156
157             instr->src_operand.type = IMM_OPERAND;
158             instr->src_operand.size = operand_width;
159
160             if (operand_width == 1) {
161                 instr->src_operand.operand = *(uint8_t *)instr_ptr;
162             } else if (operand_width == 2) {
163                 instr->src_operand.operand = *(uint16_t *)instr_ptr;
164             } else if (operand_width == 4) {
165                 instr->src_operand.operand = *(uint32_t *)instr_ptr;
166             } else {
167                 PrintError("Illegal operand width (%d)\n", operand_width);
168                 return -1;
169             }
170
171             instr_ptr += operand_width;
172
173             instr->num_operands = 2;
174
175             break;
176         }
177         case ADC_2MEM_8:
178         case ADD_2MEM_8:
179         case AND_2MEM_8:
180         case OR_2MEM_8:
181         case SUB_2MEM_8:
182         case XOR_2MEM_8:
183         case MOV_2MEM_8:
184         case ADC_2MEM:
185         case ADD_2MEM:
186         case AND_2MEM:
187         case OR_2MEM:
188         case SUB_2MEM:
189         case XOR_2MEM:
190         case MOV_2MEM: {
191             uint8_t reg_code = 0;
192
193             ret = decode_rm_operand(core, instr_ptr, form, instr, &(instr->dst_operand), &reg_code);
194
195             if (ret == -1) {
196                 PrintError("Error decoding operand\n");
197                 return -1;
198             }
199
200             instr_ptr += ret;
201
202             instr->src_operand.type = REG_OPERAND;
203             instr->src_operand.size = operand_width;
204
205             decode_gpr(core, reg_code, &(instr->src_operand));
206
207             instr->num_operands = 2;
208             break;
209         }
210         case ADC_MEM2_8:
211         case ADD_MEM2_8:
212         case AND_MEM2_8:
213         case OR_MEM2_8:
214         case SUB_MEM2_8:
215         case XOR_MEM2_8:
216         case MOV_MEM2_8:
217         case ADC_MEM2:
218         case ADD_MEM2:
219         case AND_MEM2:
220         case OR_MEM2:
221         case SUB_MEM2:
222         case XOR_MEM2:
223         case MOV_MEM2: {
224             uint8_t reg_code = 0;
225
226             ret = decode_rm_operand(core, instr_ptr, form, instr, &(instr->src_operand), &reg_code);
227
228             if (ret == -1) {
229                 PrintError("Error decoding operand\n");
230                 return -1;
231             }
232
233             instr_ptr += ret;
234
235             instr->dst_operand.size = operand_width;
236             instr->dst_operand.type = REG_OPERAND;
237             decode_gpr(core, reg_code, &(instr->dst_operand));
238
239             instr->num_operands = 2;
240
241             break;
242         }
243         case ADC_IMM2SX_8:
244         case ADD_IMM2SX_8:
245         case AND_IMM2SX_8:
246         case OR_IMM2SX_8:
247         case SUB_IMM2SX_8:
248         case XOR_IMM2SX_8: {
249             uint8_t reg_code = 0;
250
251             ret = decode_rm_operand(core, instr_ptr, form, instr, &(instr->src_operand), &reg_code);
252
253             if (ret == -1) {
254                 PrintError("Error decoding operand\n");
255                 return -1;
256             }
257
258             instr_ptr += ret;
259
260             instr->src_operand.type = IMM_OPERAND;
261             instr->src_operand.size = operand_width;
262             instr->src_operand.operand = *(sint8_t *)instr_ptr;  // sign extend.
263
264             instr_ptr += 1;
265
266             instr->num_operands = 2;
267
268             break;
269         }
270         case MOVS:
271         case MOVS_8: {
272             instr->is_str_op = 1;
273             
274             if (instr->prefixes.rep == 1) {
275                 instr->str_op_length = MASK(core->vm_regs.rcx, operand_width);
276             } else {
277                 instr->str_op_length = 1;
278             }
279
280             // Source: DS:(E)SI
281             // Destination: ES:(E)DI
282
283             instr->src_operand.type = MEM_OPERAND;
284             instr->src_operand.size = operand_width;
285             instr->src_operand.operand = get_addr_linear(core,  MASK(core->vm_regs.rsi, addr_width), &(core->segments.ds));
286
287             instr->dst_operand.type = MEM_OPERAND;
288             instr->dst_operand.size = operand_width;
289             instr->dst_operand.operand = get_addr_linear(core, MASK(core->vm_regs.rdi, addr_width), &(core->segments.es));
290
291             instr->num_operands = 2;
292
293             break;
294
295             case MOV_2CR: {
296                 uint8_t reg_code = 0;
297
298                 ret = decode_rm_operand(core, instr_ptr, form, instr, &(instr->src_operand),
299                                         &reg_code);
300
301                 if (ret == -1) {
302                     PrintError("Error decoding operand for (%s)\n", op_form_to_str(form));
303                     return -1;
304                 }
305                 
306                 instr_ptr += ret;
307
308                 instr->dst_operand.type = REG_OPERAND;
309                 instr->dst_operand.size = operand_width;
310                 decode_cr(core, reg_code, &(instr->dst_operand));
311
312                 instr->num_operands = 2;
313                 break;
314             }
315             case MOV_CR2: {
316                 uint8_t reg_code = 0;
317
318                 ret = decode_rm_operand(core, instr_ptr, form, instr, &(instr->dst_operand),
319                                         &reg_code);
320
321                 if (ret == -1) {
322                     PrintError("Error decoding operand for (%s)\n", op_form_to_str(form));
323                     return -1;
324                 }
325
326                 instr_ptr += ret;
327                 
328                 instr->src_operand.type = REG_OPERAND;
329                 instr->src_operand.size = operand_width;
330                 decode_cr(core, reg_code, &(instr->src_operand));
331
332                 instr->num_operands = 2;
333                 break;
334             }
335             case STOS:
336             case STOS_8: {
337                 instr->is_str_op = 1;
338                 
339                 if (instr->prefixes.rep == 1) {
340                     instr->str_op_length = MASK(core->vm_regs.rcx, operand_width);
341                 } else {
342                     instr->str_op_length = 1;
343                 }
344                 
345                 instr->src_operand.size = operand_width;
346                 instr->src_operand.type = REG_OPERAND;
347                 instr->src_operand.operand = (addr_t)&(core->vm_regs.rax);
348
349                 instr->dst_operand.type = MEM_OPERAND;
350                 instr->dst_operand.size = operand_width;
351                 instr->dst_operand.operand = get_addr_linear(core, MASK(core->vm_regs.rdi, addr_width), &(core->segments.es));
352
353                 instr->num_operands = 2;
354
355                 break;
356             }
357             case INVLPG: {
358                 uint8_t reg_code = 0;
359
360                 // We use the dst operand here to maintain bug-for-bug compatibility with XED
361
362                 ret = decode_rm_operand(core, instr_ptr, form, instr, &(instr->dst_operand), &reg_code);
363
364                 if (ret == -1) {
365                     PrintError("Error decoding operand for (%s)\n", op_form_to_str(form));
366                     return -1;
367                 }
368
369                 instr_ptr += ret;
370
371                 instr->num_operands = 1;
372                 break;
373             }
374             case CLTS: {
375                 // no operands. 
376                 break;
377
378             }
379         }
380         default:
381             PrintError("Invalid Instruction form: %s\n", op_form_to_str(form));
382             return -1;
383     }
384
385     return (instr_ptr - instr_start);
386 }
387
388
389 static v3_op_type_t op_form_to_type(op_form_t form) { 
390     switch (form) {
391         case LMSW:
392             return V3_OP_LMSW;
393         case SMSW:
394             return V3_OP_SMSW;
395         case CLTS:
396             return V3_OP_CLTS;
397         case INVLPG:
398             return V3_OP_INVLPG;
399
400         case MOV_CR2:
401             return V3_OP_MOVCR2;
402         case MOV_2CR:
403             return V3_OP_MOV2CR;
404
405
406         case MOV_MEM2_8:
407         case MOV_MEM2:
408         case MOV_2MEM_8:
409         case MOV_2MEM:
410         case MOV_MEM2AL_8:
411         case MOV_MEM2AX:
412         case MOV_AL2MEM_8:
413         case MOV_AX2MEM:
414         case MOV_IMM2_8:
415         case MOV_IMM2:
416             return V3_OP_MOV;
417
418         case MOVS_8:
419         case MOVS:
420             return V3_OP_MOVS;
421
422         case MOVSX_8:
423         case MOVSX:
424             return V3_OP_MOVSX;
425
426         case MOVZX_8:
427         case MOVZX:
428             return V3_OP_MOVZX;
429
430
431             
432         case ADC_2MEM_8:
433         case ADC_2MEM:
434         case ADC_MEM2_8:
435         case ADC_MEM2:
436         case ADC_IMM2_8:
437         case ADC_IMM2:
438         case ADC_IMM2SX_8:
439             return V3_OP_ADC;
440
441
442         case ADD_2MEM_8:
443         case ADD_2MEM:
444         case ADD_MEM2_8:
445         case ADD_MEM2:
446         case ADD_IMM2_8:
447         case ADD_IMM2:
448         case ADD_IMM2SX_8:
449             return V3_OP_ADD;
450
451         case AND_MEM2_8:
452         case AND_MEM2:
453         case AND_2MEM_8:
454         case AND_2MEM:
455         case AND_IMM2_8:
456         case AND_IMM2:
457         case AND_IMM2SX_8:
458             return V3_OP_AND;
459
460         case OR_2MEM_8:
461         case OR_2MEM:
462         case OR_MEM2_8:
463         case OR_MEM2:
464         case OR_IMM2_8:
465         case OR_IMM2:
466         case OR_IMM2SX_8:
467             return V3_OP_OR;
468
469         case SUB_2MEM_8:
470         case SUB_2MEM:
471         case SUB_MEM2_8:
472         case SUB_MEM2:
473         case SUB_IMM2_8:
474         case SUB_IMM2:
475         case SUB_IMM2SX_8:
476             return V3_OP_SUB;
477
478         case XOR_2MEM_8:
479         case XOR_2MEM:
480         case XOR_MEM2_8:
481         case XOR_MEM2:
482         case XOR_IMM2_8:
483         case XOR_IMM2:
484         case XOR_IMM2SX_8:
485             return V3_OP_XOR;
486
487         case INC_8:
488         case INC:
489             return V3_OP_INC;
490
491         case DEC_8:
492         case DEC:
493             return V3_OP_DEC;
494
495         case NEG_8:
496         case NEG: 
497             return V3_OP_NEG;
498
499         case NOT_8:
500         case NOT:
501             return V3_OP_NOT;
502
503         case XCHG_8:
504         case XCHG:
505             return V3_OP_XCHG;
506             
507         case SETB:
508             return V3_OP_SETB;
509         case SETBE:
510             return V3_OP_SETBE;
511         case SETL:
512             return V3_OP_SETL;
513         case SETLE:
514             return V3_OP_SETLE;
515         case SETNB:
516             return V3_OP_SETNB;
517         case SETNBE:
518             return V3_OP_SETNBE;
519         case SETNL:
520             return V3_OP_SETNL;
521         case SETNLE:
522             return V3_OP_SETNLE;
523         case SETNO:
524             return V3_OP_SETNO;
525         case SETNP:
526             return V3_OP_SETNP;
527         case SETNS:
528             return V3_OP_SETNS;
529         case SETNZ:
530             return V3_OP_SETNZ;
531         case SETP:
532             return V3_OP_SETP;
533         case SETS:
534             return V3_OP_SETS;
535         case SETZ:
536             return V3_OP_SETZ;
537         case SETO:
538             return V3_OP_SETO;
539             
540         case STOS_8:
541         case STOS:
542             return V3_OP_STOS;
543
544         case HLT:
545         case PUSHF:
546         case POPF:
547         case MOV_DR2:
548         case MOV_2DR:
549         case MOV_SR2:
550         case MOV_2SR:
551
552         default:
553             return V3_INVALID_OP;
554
555     }
556 }