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