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