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.


cleaned up the emulation code to be more general
[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
169             if (operand_width == 1) {
170                 instr->src_operand.operand = *(uint8_t *)instr_ptr;
171             } else if (operand_width == 2) {
172                 instr->src_operand.operand = *(uint16_t *)instr_ptr;
173             } else if (operand_width == 4) {
174                 instr->src_operand.operand = *(uint32_t *)instr_ptr;
175             } else {
176                 PrintError("Illegal operand width (%d)\n", operand_width);
177                 return -1;
178             }
179
180             instr->src_operand.read = 1;
181             instr->dst_operand.write = 1;
182
183             instr_ptr += operand_width;
184
185             instr->num_operands = 2;
186
187             break;
188         }
189         case ADC_2MEM_8:
190         case ADD_2MEM_8:
191         case AND_2MEM_8:
192         case OR_2MEM_8:
193         case SUB_2MEM_8:
194         case XOR_2MEM_8:
195         case MOV_2MEM_8:
196         case ADC_2MEM:
197         case ADD_2MEM:
198         case AND_2MEM:
199         case OR_2MEM:
200         case SUB_2MEM:
201         case XOR_2MEM:
202         case MOV_2MEM: {
203             uint8_t reg_code = 0;
204
205             ret = decode_rm_operand(core, instr_ptr, form, instr, &(instr->dst_operand), &reg_code);
206
207             if (ret == -1) {
208                 PrintError("Error decoding operand\n");
209                 return -1;
210             }
211
212             instr_ptr += ret;
213
214             instr->src_operand.type = REG_OPERAND;
215             instr->src_operand.size = operand_width;
216
217             instr->src_operand.read = 1;
218             instr->dst_operand.write = 1;
219
220
221             decode_gpr(core, reg_code, &(instr->src_operand));
222
223             instr->num_operands = 2;
224             break;
225         }
226         case ADC_MEM2_8:
227         case ADD_MEM2_8:
228         case AND_MEM2_8:
229         case OR_MEM2_8:
230         case SUB_MEM2_8:
231         case XOR_MEM2_8:
232         case MOV_MEM2_8:
233         case ADC_MEM2:
234         case ADD_MEM2:
235         case AND_MEM2:
236         case OR_MEM2:
237         case SUB_MEM2:
238         case XOR_MEM2:
239         case MOV_MEM2: {
240             uint8_t reg_code = 0;
241
242             ret = decode_rm_operand(core, instr_ptr, form, instr, &(instr->src_operand), &reg_code);
243
244             if (ret == -1) {
245                 PrintError("Error decoding operand\n");
246                 return -1;
247             }
248
249             instr_ptr += ret;
250
251             instr->dst_operand.size = operand_width;
252             instr->dst_operand.type = REG_OPERAND;
253             decode_gpr(core, reg_code, &(instr->dst_operand));
254
255             instr->src_operand.read = 1;
256             instr->dst_operand.write = 1;
257
258             instr->num_operands = 2;
259
260             break;
261         }
262         case ADC_IMM2SX_8:
263         case ADD_IMM2SX_8:
264         case AND_IMM2SX_8:
265         case OR_IMM2SX_8:
266         case SUB_IMM2SX_8:
267         case XOR_IMM2SX_8: {
268             uint8_t reg_code = 0;
269
270             ret = decode_rm_operand(core, instr_ptr, form, instr, &(instr->dst_operand), &reg_code);
271
272
273             if (ret == -1) {
274                 PrintError("Error decoding operand\n");
275                 return -1;
276             }
277
278             instr_ptr += ret;
279
280             instr->src_operand.type = IMM_OPERAND;
281             instr->src_operand.size = operand_width;
282             instr->src_operand.operand = *(sint8_t *)instr_ptr;  // sign extend.
283
284             instr->src_operand.read = 1;
285             instr->dst_operand.write = 1;
286
287             instr_ptr += 1;
288
289             instr->num_operands = 2;
290
291             break;
292         }
293         case MOVS:
294         case MOVS_8: {
295             instr->is_str_op = 1;
296             
297             if (instr->prefixes.rep == 1) {
298                 instr->str_op_length = MASK(core->vm_regs.rcx, operand_width);
299             } else {
300                 instr->str_op_length = 1;
301             }
302
303             // Source: DS:(E)SI
304             // Destination: ES:(E)DI
305
306             instr->src_operand.type = MEM_OPERAND;
307             instr->src_operand.size = operand_width;
308             instr->src_operand.operand = get_addr_linear(core,  MASK(core->vm_regs.rsi, addr_width), &(core->segments.ds));
309
310
311             instr->dst_operand.type = MEM_OPERAND;
312             instr->dst_operand.size = operand_width;
313             instr->dst_operand.operand = get_addr_linear(core, MASK(core->vm_regs.rdi, addr_width), &(core->segments.es));
314
315
316             instr->src_operand.read = 1;
317             instr->dst_operand.write = 1;
318
319             instr->num_operands = 2;
320
321             break;
322
323             case MOV_2CR: {
324                 uint8_t reg_code = 0;
325
326                 ret = decode_rm_operand(core, instr_ptr, form, instr, &(instr->src_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->dst_operand.type = REG_OPERAND;
337                 instr->dst_operand.size = operand_width;
338                 decode_cr(core, reg_code, &(instr->dst_operand));
339
340                 instr->src_operand.read = 1;
341                 instr->dst_operand.write = 1;
342
343                 instr->num_operands = 2;
344                 break;
345             }
346             case MOV_CR2: {
347                 uint8_t reg_code = 0;
348
349                 ret = decode_rm_operand(core, instr_ptr, form, instr, &(instr->dst_operand),
350                                         &reg_code);
351
352
353                 if (ret == -1) {
354                     PrintError("Error decoding operand for (%s)\n", op_form_to_str(form));
355                     return -1;
356                 }
357
358                 instr_ptr += ret;
359                 
360                 instr->src_operand.type = REG_OPERAND;
361                 instr->src_operand.size = operand_width;
362                 decode_cr(core, reg_code, &(instr->src_operand));
363
364                 instr->src_operand.read = 1;
365                 instr->dst_operand.write = 1;
366
367                 instr->num_operands = 2;
368                 break;
369             }
370             case STOS:
371             case STOS_8: {
372                 instr->is_str_op = 1;
373                 
374                 if (instr->prefixes.rep == 1) {
375                     instr->str_op_length = MASK(core->vm_regs.rcx, operand_width);
376                 } else {
377                     instr->str_op_length = 1;
378                 }
379                 
380                 instr->src_operand.size = operand_width;
381                 instr->src_operand.type = REG_OPERAND;
382                 instr->src_operand.operand = (addr_t)&(core->vm_regs.rax);
383
384                 instr->dst_operand.type = MEM_OPERAND;
385                 instr->dst_operand.size = operand_width;
386                 instr->dst_operand.operand = get_addr_linear(core, MASK(core->vm_regs.rdi, addr_width), &(core->segments.es));
387
388                 instr->src_operand.read = 1;
389                 instr->dst_operand.write = 1;
390
391                 instr->num_operands = 2;
392
393                 break;
394             }
395             case INVLPG: {
396                 uint8_t reg_code = 0;
397
398                 ret = decode_rm_operand(core, instr_ptr, form, instr, &(instr->dst_operand), &reg_code);
399
400                 if (ret == -1) {
401                     PrintError("Error decoding operand for (%s)\n", op_form_to_str(form));
402                     return -1;
403                 }
404
405                 instr_ptr += ret;
406
407                 instr->num_operands = 1;
408                 break;
409             }
410             case CLTS: {
411                 // no operands. 
412                 break;
413
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 }