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.


reverted syscall changes
[palacios.git] / palacios / src / palacios / vmm_decoder.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
21 #include <palacios/vmm_decoder.h>
22
23
24
25
26
27 uint8_t v3_get_prefixes(uint8_t * instr, struct x86_prefixes * prefixes) {
28     uint8_t * instr_cursor = instr;
29
30     while (1) {
31         switch (*instr_cursor) {
32             case 0xF0:      // lock
33                 prefixes->lock = 1;
34                 break;
35
36             case 0xF2:      // REPNE/REPNZ
37                 prefixes->repnz = 1;
38                 prefixes->repne = 1;
39                 break;
40
41             case 0xF3:      // REP or REPE/REPZ
42                 prefixes->rep = 1;
43                 prefixes->repe = 1;
44                 prefixes->repz = 1; 
45                 break;
46
47             case 0x2E:      // CS override or Branch hint not taken (with Jcc instr_cursors)
48                 prefixes->cs_override = 1;
49                 prefixes->br_not_taken = 1;
50                 break;
51
52             case 0x36:      // SS override
53                 prefixes->ss_override = 1;
54                 break;
55
56             case 0x3E:      // DS override or Branch hint taken (with Jcc instr_cursors)
57                 prefixes->ds_override = 1;
58                 prefixes->br_taken = 1;
59                 break;
60
61             case 0x26:      // ES override
62                 prefixes->es_override = 1;
63                 break;
64
65             case 0x64:      // FS override
66                 prefixes->fs_override = 1;
67                 break;
68       
69             case 0x65:      // GS override
70                 prefixes->gs_override = 1;
71                 break;
72
73             case 0x66:      // operand size override
74                 prefixes->op_size = 1;
75                 break;
76
77             case 0x67:    // address size override
78                 prefixes->addr_size = 1;
79                 break;
80
81             default:
82                 return (instr_cursor - instr);
83         }
84
85         instr_cursor++;
86     }
87 }
88
89 void v3_strip_rep_prefix(uchar_t * instr, int length) {
90     int read_ctr = 0;
91     int write_ctr = 0;
92     int found = 0;
93
94     while (read_ctr < length) {
95         if ((!found) && 
96             ( (instr[read_ctr] == 0xF2) ||
97               (instr[read_ctr] == 0xF3))) {
98             read_ctr++;
99             found = 1;
100         } else {
101             instr[write_ctr] = instr[read_ctr];
102             write_ctr++;
103             read_ctr++;
104         }
105     }
106 }
107
108
109 static char * op_type_to_str(v3_op_type_t type) {
110     switch (type) {
111         case V3_OP_MOVCR2: return "V3_OP_MOVCR2"; 
112         case V3_OP_MOV2CR: return "V3_OP_MOV2CR"; 
113         case V3_OP_SMSW: return "V3_OP_SMSW"; 
114         case V3_OP_LMSW: return "V3_OP_LMSW"; 
115         case V3_OP_CLTS: return "V3_OP_CLTS";
116         case V3_OP_INVLPG: return "V3_OP_INVLPG";
117         case V3_OP_ADC: return "V3_OP_ADC"; 
118         case V3_OP_ADD: return "V3_OP_ADD";
119         case V3_OP_AND: return "V3_OP_AND"; 
120         case V3_OP_OR: return "V3_OP_OR"; 
121         case V3_OP_XOR: return "V3_OP_XOR"; 
122         case V3_OP_SUB: return "V3_OP_SUB";
123         case V3_OP_INC: return "V3_OP_INC"; 
124         case V3_OP_DEC: return "V3_OP_DEC"; 
125         case V3_OP_NEG: return "V3_OP_NEG"; 
126         case V3_OP_MOV: return "V3_OP_MOV"; 
127         case V3_OP_NOT: return "V3_OP_NOT"; 
128         case V3_OP_XCHG: return "V3_OP_XCHG"; 
129         case V3_OP_SETB: return "V3_OP_SETB"; 
130         case V3_OP_SETBE: return "V3_OP_SETBE"; 
131         case V3_OP_SETL: return "V3_OP_SETL"; 
132         case V3_OP_SETLE: return "V3_OP_SETLE"; 
133         case V3_OP_SETNB: return "V3_OP_SETNB"; 
134         case V3_OP_SETNBE: return "V3_OP_SETNBE"; 
135         case V3_OP_SETNL: return "V3_OP_SETNL"; 
136         case V3_OP_SETNLE: return "V3_OP_SETNLE"; 
137         case V3_OP_SETNO: return "V3_OP_SETNO"; 
138         case V3_OP_SETNP: return "V3_OP_SETNP";
139         case V3_OP_SETNS: return "V3_OP_SETNS"; 
140         case V3_OP_SETNZ: return "V3_OP_SETNZ"; 
141         case V3_OP_SETO: return "V3_OP_SETO"; 
142         case V3_OP_SETP: return "V3_OP_SETP"; 
143         case V3_OP_SETS: return "V3_OP_SETS"; 
144         case V3_OP_SETZ: return "V3_OP_SETZ"; 
145         case V3_OP_MOVS: return "V3_OP_MOVS"; 
146         case V3_OP_STOS: return "V3_OP_STOS"; 
147         case V3_OP_MOVZX: return "V3_OP_MOVZX"; 
148         case V3_OP_MOVSX: return "V3_OP_MOVSX";
149         case V3_INVALID_OP: 
150         default:
151             return "V3_INVALID_OP";
152     }
153 }
154
155
156 static char * operand_type_to_str(v3_operand_type_t op) {
157     switch (op) {
158         case REG_OPERAND: return "REG_OPERAND";
159         case MEM_OPERAND: return "MEM_OPERAND";
160         case IMM_OPERAND: return "IMM_OPERAND";
161         default:
162             return "INVALID_OPERAND";
163     }
164 }
165
166
167 static const ullong_t mask_1 = 0x00000000000000ffLL;
168 static const ullong_t mask_2 = 0x000000000000ffffLL;
169 static const ullong_t mask_4 = 0x00000000ffffffffLL;
170 static const ullong_t mask_8 = 0xffffffffffffffffLL;
171
172
173 #define MASK(val, length) ({                    \
174             ullong_t mask = 0x0LL;              \
175             switch (length) {                   \
176                 case 1:                         \
177                     mask = mask_1;              \
178                     break;                      \
179                 case 2:                         \
180                     mask = mask_2;              \
181                     break;                      \
182                 case 4:                         \
183                     mask = mask_4;              \
184                     break;                      \
185                 case 8:                         \
186                     mask = mask_8;              \
187                     break;                      \
188             }                                   \
189             val & mask;                         \
190         })
191
192 void v3_print_instr(struct x86_instr * instr) {
193     V3_Print("Instr: %s (Len: %d)\n", op_type_to_str(instr->op_type), instr->instr_length);
194
195     V3_Print("Prefixes= %x\n", instr->prefixes.val);
196
197     if (instr->is_str_op) {
198         V3_Print("String OP (len=%d)\n", (uint32_t)instr->str_op_length);
199     }
200
201     V3_Print("Number of operands: %d\n", instr->num_operands);
202
203     if (instr->num_operands > 0) {
204         V3_Print("Src Operand (%s)\n", operand_type_to_str(instr->src_operand.type));
205         V3_Print("\tLen=%d (Addr: %p)\n", instr->src_operand.size, 
206                  (void *)instr->src_operand.operand);
207         if (instr->src_operand.type == REG_OPERAND) {
208             V3_Print("\tVal: 0x%llx\n", MASK(*(uint64_t *)(instr->src_operand.operand), instr->src_operand.size));
209         }
210     }
211
212     if (instr->num_operands > 1) {
213         V3_Print("Dst Operand (%s)\n", operand_type_to_str(instr->dst_operand.type));
214         V3_Print("\tLen=%d (Addr: %p)\n", instr->dst_operand.size, 
215                  (void *)instr->dst_operand.operand);
216         if (instr->dst_operand.type == REG_OPERAND) {
217             V3_Print("\tVal: 0x%llx\n", MASK(*(uint64_t *)(instr->dst_operand.operand), instr->dst_operand.size));
218         }
219     }
220
221     if (instr->num_operands > 2) {
222         V3_Print("Third Operand (%s)\n", operand_type_to_str(instr->third_operand.type));
223         V3_Print("\tLen=%d (Addr: %p)\n", instr->third_operand.size, 
224                  (void *)instr->third_operand.operand);
225         if (instr->third_operand.type == REG_OPERAND) {
226             V3_Print("\tVal: 0x%llx\n", MASK(*(uint64_t *)(instr->third_operand.operand), instr->third_operand.size));
227         }
228     }
229 }
230
231