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.


build fixes to merge the Palacios configuration parameters with Linux parameters.
[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 CLTS: {
463             // no operands. 
464             break;
465             
466         }
467         default:
468             PrintError("Invalid Instruction form: %s\n", op_form_to_str(form));
469             return -1;
470     }
471
472     return (instr_ptr - instr_start);
473 }
474
475
476 static v3_op_type_t op_form_to_type(op_form_t form) { 
477     switch (form) {
478         case LMSW:
479             return V3_OP_LMSW;
480         case SMSW:
481             return V3_OP_SMSW;
482         case CLTS:
483             return V3_OP_CLTS;
484         case INVLPG:
485             return V3_OP_INVLPG;
486
487         case MOV_CR2:
488             return V3_OP_MOVCR2;
489         case MOV_2CR:
490             return V3_OP_MOV2CR;
491
492
493         case MOV_MEM2_8:
494         case MOV_MEM2:
495         case MOV_2MEM_8:
496         case MOV_2MEM:
497         case MOV_MEM2AL_8:
498         case MOV_MEM2AX:
499         case MOV_AL2MEM_8:
500         case MOV_AX2MEM:
501         case MOV_IMM2_8:
502         case MOV_IMM2:
503             return V3_OP_MOV;
504
505         case MOVS_8:
506         case MOVS:
507             return V3_OP_MOVS;
508
509         case MOVSX_8:
510         case MOVSX:
511             return V3_OP_MOVSX;
512
513         case MOVZX_8:
514         case MOVZX:
515             return V3_OP_MOVZX;
516
517
518             
519         case ADC_2MEM_8:
520         case ADC_2MEM:
521         case ADC_MEM2_8:
522         case ADC_MEM2:
523         case ADC_IMM2_8:
524         case ADC_IMM2:
525         case ADC_IMM2SX_8:
526             return V3_OP_ADC;
527
528
529         case ADD_2MEM_8:
530         case ADD_2MEM:
531         case ADD_MEM2_8:
532         case ADD_MEM2:
533         case ADD_IMM2_8:
534         case ADD_IMM2:
535         case ADD_IMM2SX_8:
536             return V3_OP_ADD;
537
538         case AND_MEM2_8:
539         case AND_MEM2:
540         case AND_2MEM_8:
541         case AND_2MEM:
542         case AND_IMM2_8:
543         case AND_IMM2:
544         case AND_IMM2SX_8:
545             return V3_OP_AND;
546
547         case OR_2MEM_8:
548         case OR_2MEM:
549         case OR_MEM2_8:
550         case OR_MEM2:
551         case OR_IMM2_8:
552         case OR_IMM2:
553         case OR_IMM2SX_8:
554             return V3_OP_OR;
555
556         case SUB_2MEM_8:
557         case SUB_2MEM:
558         case SUB_MEM2_8:
559         case SUB_MEM2:
560         case SUB_IMM2_8:
561         case SUB_IMM2:
562         case SUB_IMM2SX_8:
563             return V3_OP_SUB;
564
565         case XOR_2MEM_8:
566         case XOR_2MEM:
567         case XOR_MEM2_8:
568         case XOR_MEM2:
569         case XOR_IMM2_8:
570         case XOR_IMM2:
571         case XOR_IMM2SX_8:
572             return V3_OP_XOR;
573
574         case INC_8:
575         case INC:
576             return V3_OP_INC;
577
578         case DEC_8:
579         case DEC:
580             return V3_OP_DEC;
581
582         case NEG_8:
583         case NEG: 
584             return V3_OP_NEG;
585
586         case NOT_8:
587         case NOT:
588             return V3_OP_NOT;
589
590         case XCHG_8:
591         case XCHG:
592             return V3_OP_XCHG;
593             
594         case SETB:
595             return V3_OP_SETB;
596         case SETBE:
597             return V3_OP_SETBE;
598         case SETL:
599             return V3_OP_SETL;
600         case SETLE:
601             return V3_OP_SETLE;
602         case SETNB:
603             return V3_OP_SETNB;
604         case SETNBE:
605             return V3_OP_SETNBE;
606         case SETNL:
607             return V3_OP_SETNL;
608         case SETNLE:
609             return V3_OP_SETNLE;
610         case SETNO:
611             return V3_OP_SETNO;
612         case SETNP:
613             return V3_OP_SETNP;
614         case SETNS:
615             return V3_OP_SETNS;
616         case SETNZ:
617             return V3_OP_SETNZ;
618         case SETP:
619             return V3_OP_SETP;
620         case SETS:
621             return V3_OP_SETS;
622         case SETZ:
623             return V3_OP_SETZ;
624         case SETO:
625             return V3_OP_SETO;
626             
627         case STOS_8:
628         case STOS:
629             return V3_OP_STOS;
630
631         case HLT:
632         case PUSHF:
633         case POPF:
634         case MOV_DR2:
635         case MOV_2DR:
636         case MOV_SR2:
637         case MOV_2SR:
638
639         default:
640             return V3_INVALID_OP;
641
642     }
643 }