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.


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