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.


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