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 updates
[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 /* Disgusting mask hack...
25    I can't think right now, so we'll do it this way...
26 */
27 static const ullong_t mask_1 = 0x00000000000000ffLL;
28 static const ullong_t mask_2 = 0x000000000000ffffLL;
29 static const ullong_t mask_4 = 0x00000000ffffffffLL;
30 static const ullong_t mask_8 = 0xffffffffffffffffLL;
31
32
33 #define MASK(val, length) ({                    \
34             ullong_t mask = 0x0LL;              \
35             switch (length) {                   \
36                 case 1:                         \
37                     mask = mask_1;              \
38                     break;                      \
39                 case 2:                         \
40                     mask = mask_2;              \
41                     break;                      \
42                 case 4:                         \
43                     mask = mask_4;              \
44                     break;                      \
45                 case 8:                         \
46                     mask = mask_8;              \
47                     break;                      \
48             }                                   \
49             val & mask;                         \
50         })
51
52 static v3_op_type_t op_form_to_type(op_form_t form);
53 static int parse_operands(struct guest_info * core, uint8_t * instr_ptr, struct x86_instr * instr, op_form_t form);
54
55
56 int v3_disasm(struct guest_info * info, void *instr_ptr, addr_t * rip, int mark) {
57     return 0;
58 }
59
60
61 int v3_init_decoder(struct guest_info * core) { 
62     return 0;
63 }
64
65
66 int v3_deinit_decoder(struct guest_info * core) {
67     return 0;
68 }
69
70
71 int v3_encode(struct guest_info * info, struct x86_instr * instr, uint8_t * instr_buf) {
72     return 0;
73 }
74
75
76 int v3_decode(struct guest_info * core, addr_t instr_ptr, struct x86_instr * instr) {
77     op_form_t form = INVALID_INSTR; 
78     int ret = 0;
79     int length = 0;
80
81     memset(instr, 0, sizeof(struct x86_instr));
82
83     // scan for prefixes
84     length = v3_get_prefixes((uint8_t *)instr_ptr, &(instr->prefixes));
85
86
87     // check for REX prefix
88
89
90     form = op_code_to_form((uint8_t *)(instr_ptr + length), &length);
91
92     if (form == INVALID_INSTR) {
93         PrintError("Could not find instruction form (%x)\n", *(uint32_t *)(instr_ptr + length));
94         return -1;
95     }
96
97     instr->op_type = op_form_to_type(form);
98
99     ret = parse_operands(core, (uint8_t *)(instr_ptr + length), instr, form);
100
101     if (ret == -1) {
102         PrintError("Could not parse instruction operands\n");
103         return -1;
104     }
105     length += ret;
106     
107
108     instr->instr_length += length;
109
110
111     return 0;
112 }
113
114
115 static int parse_operands(struct guest_info * core, uint8_t * instr_ptr, 
116                           struct x86_instr * instr, op_form_t form) {
117     // get operational mode of the guest for operand width
118     uint8_t operand_width = get_operand_width(core, instr, form);
119     uint8_t addr_width = get_addr_width(core, instr, form);;
120     int ret = 0;
121     uint8_t * instr_start = instr_ptr;
122     
123
124     switch (form) {
125         case ADC_IMM2_8:
126         case ADD_IMM2_8:
127         case AND_IMM2_8:
128         case OR_IMM2_8:
129         case SUB_IMM2_8:
130         case XOR_IMM2_8:
131         case MOV_IMM2_8:
132         case ADC_IMM2:
133         case ADD_IMM2:
134         case AND_IMM2:  
135         case OR_IMM2:
136         case SUB_IMM2:
137         case XOR_IMM2: 
138         case MOV_IMM2:{
139             uint8_t reg_code = 0;
140
141             instr->dst_operand.size = operand_width;
142
143             ret = decode_rm_operand(core, instr_ptr, &(instr->dst_operand), &reg_code);
144
145             if (ret == -1) {
146                 PrintError("Error decoding operand\n");
147                 return -1;
148             }
149
150             instr_ptr += ret;
151
152             instr->src_operand.type = IMM_OPERAND;
153             instr->src_operand.size = operand_width;
154
155             if (operand_width == 1) {
156                 instr->src_operand.operand = *(uint8_t *)instr_ptr;
157             } else if (operand_width == 2) {
158                 instr->src_operand.operand = *(uint16_t *)instr_ptr;
159             } else if (operand_width == 4) {
160                 instr->src_operand.operand = *(uint32_t *)instr_ptr;
161             } else {
162                 PrintError("Illegal operand width (%d)\n", operand_width);
163                 return -1;
164             }
165
166             instr_ptr += operand_width;
167
168             instr->num_operands = 2;
169
170             break;
171         }
172         case ADC_2MEM_8:
173         case ADD_2MEM_8:
174         case AND_2MEM_8:
175         case OR_2MEM_8:
176         case SUB_2MEM_8:
177         case XOR_2MEM_8:
178         case MOV_2MEM_8:
179         case ADC_2MEM:
180         case ADD_2MEM:
181         case AND_2MEM:
182         case OR_2MEM:
183         case SUB_2MEM:
184         case XOR_2MEM:
185         case MOV_2MEM: {
186             uint8_t reg_code = 0;
187
188             instr->dst_operand.size = operand_width;
189
190             ret = decode_rm_operand(core, instr_ptr, &(instr->dst_operand), &reg_code);
191
192             if (ret == -1) {
193                 PrintError("Error decoding operand\n");
194                 return -1;
195             }
196
197             instr_ptr += ret;
198
199             instr->src_operand.type = REG_OPERAND;
200             instr->src_operand.size = operand_width;
201
202             decode_gpr(&(core->vm_regs), reg_code, &(instr->src_operand));
203
204             instr->num_operands = 2;
205             break;
206         }
207         case ADC_MEM2_8:
208         case ADD_MEM2_8:
209         case AND_MEM2_8:
210         case OR_MEM2_8:
211         case SUB_MEM2_8:
212         case XOR_MEM2_8:
213         case MOV_MEM2_8:
214         case ADC_MEM2:
215         case ADD_MEM2:
216         case AND_MEM2:
217         case OR_MEM2:
218         case SUB_MEM2:
219         case XOR_MEM2:
220         case MOV_MEM2: {
221             uint8_t reg_code = 0;
222             instr->src_operand.size = operand_width;
223
224             ret = decode_rm_operand(core, instr_ptr, &(instr->src_operand), &reg_code);
225
226             if (ret == -1) {
227                 PrintError("Error decoding operand\n");
228                 return -1;
229             }
230
231             instr_ptr += ret;
232
233             instr->dst_operand.size = operand_width;
234             instr->dst_operand.type = REG_OPERAND;
235             decode_gpr(&(core->vm_regs), reg_code, &(instr->dst_operand));
236
237             instr->num_operands = 2;
238
239             break;
240         }
241         case ADC_IMM2SX_8:
242         case ADD_IMM2SX_8:
243         case AND_IMM2SX_8:
244         case OR_IMM2SX_8:
245         case SUB_IMM2SX_8:
246         case XOR_IMM2SX_8: {
247             uint8_t reg_code = 0;
248             instr->src_operand.size = operand_width;
249
250             ret = decode_rm_operand(core, instr_ptr, &(instr->src_operand), &reg_code);
251
252             if (ret == -1) {
253                 PrintError("Error decoding operand\n");
254                 return -1;
255             }
256
257             instr_ptr += ret;
258
259             instr->src_operand.type = IMM_OPERAND;
260             instr->src_operand.size = operand_width;
261             instr->src_operand.operand = *(sint8_t *)instr_ptr;  // sign extend.
262
263             instr_ptr += 1;
264
265             instr->num_operands = 2;
266
267             break;
268         }
269         case MOVS:
270         case MOVS_8: {
271             instr->is_str_op = 1;
272             
273             if (instr->prefixes.rep == 1) {
274                 instr->str_op_length = MASK(core->vm_regs.rcx, operand_width);
275             } else {
276                 instr->str_op_length = 1;
277             }
278
279             // Source: DS:(E)SI
280             // Source: ES:(E)DI
281
282             instr->src_operand.type = MEM_OPERAND;
283             instr->src_operand.size = operand_width;
284             instr->src_operand.operand = core->segments.ds.base + MASK(core->vm_regs.rsi, addr_width);
285
286             instr->src_operand.type = MEM_OPERAND;
287             instr->src_operand.size = operand_width;
288             instr->src_operand.operand = core->segments.es.base + MASK(core->vm_regs.rdi, addr_width);
289
290             instr->num_operands = 2;
291
292             break;
293         }
294         default:
295             PrintError("Invalid Instruction form: %d\n", form);
296             return -1;
297     }
298
299     return (instr_ptr - instr_start);
300 }
301
302
303 static v3_op_type_t op_form_to_type(op_form_t form) { 
304     switch (form) {
305         case LMSW:
306             return V3_OP_LMSW;
307         case SMSW:
308             return V3_OP_SMSW;
309         case CLTS:
310             return V3_OP_CLTS;
311         case INVLPG:
312             return V3_OP_INVLPG;
313
314         case MOV_CR2:
315             return V3_OP_MOVCR2;
316         case MOV_2CR:
317             return V3_OP_MOV2CR;
318
319
320         case MOV_MEM2_8:
321         case MOV_MEM2:
322         case MOV_2MEM_8:
323         case MOV_2MEM:
324         case MOV_MEM2AL_8:
325         case MOV_MEM2AX:
326         case MOV_AL2MEM_8:
327         case MOV_AX2MEM:
328         case MOV_IMM2_8:
329         case MOV_IMM2:
330             return V3_OP_MOV;
331
332         case MOVS_8:
333         case MOVS:
334             return V3_OP_MOVS;
335
336         case MOVSX_8:
337         case MOVSX:
338             return V3_OP_MOVSX;
339
340         case MOVZX_8:
341         case MOVZX:
342             return V3_OP_MOVZX;
343
344
345             
346         case ADC_2MEM_8:
347         case ADC_2MEM:
348         case ADC_MEM2_8:
349         case ADC_MEM2:
350         case ADC_IMM2_8:
351         case ADC_IMM2:
352         case ADC_IMM2SX_8:
353             return V3_OP_ADC;
354
355
356         case ADD_2MEM_8:
357         case ADD_2MEM:
358         case ADD_MEM2_8:
359         case ADD_MEM2:
360         case ADD_IMM2_8:
361         case ADD_IMM2:
362         case ADD_IMM2SX_8:
363             return V3_OP_ADD;
364
365         case AND_MEM2_8:
366         case AND_MEM2:
367         case AND_2MEM_8:
368         case AND_2MEM:
369         case AND_IMM2_8:
370         case AND_IMM2:
371         case AND_IMM2SX_8:
372             return V3_OP_AND;
373
374         case OR_2MEM_8:
375         case OR_2MEM:
376         case OR_MEM2_8:
377         case OR_MEM2:
378         case OR_IMM2_8:
379         case OR_IMM2:
380         case OR_IMM2SX_8:
381             return V3_OP_OR;
382
383         case SUB_2MEM_8:
384         case SUB_2MEM:
385         case SUB_MEM2_8:
386         case SUB_MEM2:
387         case SUB_IMM2_8:
388         case SUB_IMM2:
389         case SUB_IMM2SX_8:
390             return V3_OP_SUB;
391
392         case XOR_2MEM_8:
393         case XOR_2MEM:
394         case XOR_MEM2_8:
395         case XOR_MEM2:
396         case XOR_IMM2_8:
397         case XOR_IMM2:
398         case XOR_IMM2SX_8:
399             return V3_OP_XOR;
400
401         case INC_8:
402         case INC:
403             return V3_OP_INC;
404
405         case DEC_8:
406         case DEC:
407             return V3_OP_DEC;
408
409         case NEG_8:
410         case NEG: 
411             return V3_OP_NEG;
412
413         case NOT_8:
414         case NOT:
415             return V3_OP_NOT;
416
417         case XCHG_8:
418         case XCHG:
419             return V3_OP_XCHG;
420             
421         case SETB:
422             return V3_OP_SETB;
423         case SETBE:
424             return V3_OP_SETBE;
425         case SETL:
426             return V3_OP_SETL;
427         case SETLE:
428             return V3_OP_SETLE;
429         case SETNB:
430             return V3_OP_SETNB;
431         case SETNBE:
432             return V3_OP_SETNBE;
433         case SETNL:
434             return V3_OP_SETNL;
435         case SETNLE:
436             return V3_OP_SETNLE;
437         case SETNO:
438             return V3_OP_SETNO;
439         case SETNP:
440             return V3_OP_SETNP;
441         case SETNS:
442             return V3_OP_SETNS;
443         case SETNZ:
444             return V3_OP_SETNZ;
445         case SETP:
446             return V3_OP_SETP;
447         case SETS:
448             return V3_OP_SETS;
449         case SETZ:
450             return V3_OP_SETZ;
451         case SETO:
452             return V3_OP_SETO;
453             
454         case STOS_8:
455         case STOS:
456             return V3_OP_STOS;
457
458         case HLT:
459         case PUSHF:
460         case POPF:
461         case MOV_DR2:
462         case MOV_2DR:
463         case MOV_SR2:
464         case MOV_2SR:
465
466         default:
467             return V3_INVALID_OP;
468
469     }
470 }