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.


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