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.


initial checking of internal decoder
[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
22
23 /* .... Giant fucking switch tables */
24
25
26
27 #define MODRM_MOD(x) (((x) >> 6) & 0x3)
28 #define MODRM_REG(x) (((x) >> 3) & 0x7)
29 #define MODRM_RM(x)  ((x) & 0x7)
30
31 struct modrm_byte {
32     uint_t rm   :   3;
33     uint_t reg  :   3;
34     uint_t mod  :   2;
35 } __attribute__((packed));
36
37
38 #define SIB_BASE(x) (((x) >> 6) & 0x3)
39 #define SIB_INDEX(x) (((x) >> 3) & 0x7)
40 #define SIB_SCALE(x) ((x) & 0x7)
41
42 struct sib_byte {
43     uint_t base     :   3;
44     uint_t index    :   3;
45     uint_t scale    :   2;
46 } __attribute__((packed));
47
48
49
50
51 typedef enum {
52     INVALID_INSTR,
53     LMSW,
54     SMSW,
55     CLTS,
56     INVLPG,
57
58     MOV_CR2,
59     MOV_2CR,
60     MOV_DR2,
61     MOV_2DR,
62     MOV_SR2,
63     MOV_2SR,
64
65     MOV_2GPR_8,
66     MOV_2GPR,
67     MOV_GPR2_8,
68     MOV_GPR2,
69     MOV_MEM2AL_8,
70     MOV_MEM2AX,
71     MOV_AL2MEM_8,
72     MOV_AX2MEM,
73     MOV_IMM2_8,
74     MOV_IMM2,
75
76     MOVS_8,
77     MOVS,
78     MOVSX_8,
79     MOVSX,
80     MOVZX_8,
81     MOVZX,
82
83     HLT,
84     PUSHF,
85     POPF,
86
87     ADC_2MEM_8,
88     ADC_2MEM,
89     ADC_MEM2_8,
90     ADC_MEM2,
91     ADC_IMM2_8,
92     ADC_IMM2,
93     ADC_IMM2SX_8,
94     ADD_IMM2_8,
95     ADD_IMM2,
96     ADD_IMM2SX_8,
97     ADD_2MEM_8,
98     ADD_2MEM,
99     ADD_MEM2_8,
100     ADD_MEM2,
101     AND_MEM2_8,
102     AND_MEM2,
103     AND_2MEM_8,
104     AND_2MEM,
105     AND_IMM2_8,
106     AND_IMM2,
107     AND_IMM2SX_8,
108     OR_2MEM_8,
109     OR_2MEM,
110     OR_MEM2_8,
111     OR_MEM2,
112     OR_IMM2_8,
113     OR_IMM2,
114     OR_IMM2SX_8,
115     SUB_2MEM_8,
116     SUB_2MEM,
117     SUB_MEM2_8,
118     SUB_MEM2,
119     SUB_IMM2_8,
120     SUB_IMM2,
121     SUB_IMM2SX_8,
122     XOR_2MEM_8,
123     XOR_2MEM,
124     XOR_MEM2_8,
125     XOR_MEM2,
126     XOR_IMM2_8,
127     XOR_IMM2,
128     XOR_IMM2SX_8,
129
130     INC_8,
131     INC,
132     DEC_8,
133     DEC,
134     NEG_8,
135     NEG, 
136     NOT_8,
137     NOT,
138     XCHG_8,
139     XCHG,
140
141     SETB,
142     SETBE,
143     SETL,
144     SETLE,
145     SETNB,
146     SETNBE,
147     SETNL,
148     SETNLE,
149     SETNO,
150     SETNP,
151     SETNS,
152     SETNZ,
153     SETP,
154     SETS,
155     SETZ,
156     SETO,
157
158     STOS_8,
159     STOS
160 } op_form_t;
161
162 static op_form_t op_code_to_form(uint8_t * instr);
163
164
165
166 typedef enum {INVALID_ADDR_TYPE, REG, DISP0, DISP8, DISP16, DISP32} modrm_mode_t;
167 typedef enum {INVALID_REG_SIZE, REG64, REG32, REG16, REG8} reg_size_t;
168
169
170 struct v3_gprs;
171
172 static inline addr_t decode_register(struct v3_gprs * gprs, char reg_code, reg_size_t reg_size) {
173     addr_t reg_addr;
174
175     switch (reg_code) {
176         case 0:
177             reg_addr = (addr_t)&(gprs->rax);
178             break;
179         case 1:
180             reg_addr = (addr_t)&(gprs->rcx);
181             break;
182         case 2:
183             reg_addr = (addr_t)&(gprs->rdx);
184             break;
185         case 3:
186             reg_addr = (addr_t)&(gprs->rbx);
187             break;
188         case 4:
189             if (reg_size == REG8) {
190                 reg_addr = (addr_t)&(gprs->rax) + 1;
191             } else {
192                 reg_addr = (addr_t)&(gprs->rsp);
193             }
194             break;
195         case 5:
196             if (reg_size == REG8) {
197                 reg_addr = (addr_t)&(gprs->rcx) + 1;
198             } else {
199                 reg_addr = (addr_t)&(gprs->rbp);
200             }
201             break;
202         case 6:
203             if (reg_size == REG8) {
204                 reg_addr = (addr_t)&(gprs->rdx) + 1;
205             } else {
206                 reg_addr = (addr_t)&(gprs->rsi);
207             }
208             break;
209         case 7:
210             if (reg_size == REG8) {
211                 reg_addr = (addr_t)&(gprs->rbx) + 1;
212             } else {
213                 reg_addr = (addr_t)&(gprs->rdi);
214             }
215             break;
216         default:
217             reg_addr = 0;
218             break;
219     }
220
221     return reg_addr;
222 }
223
224
225
226 static inline v3_operand_type_t decode_operands16(struct v3_gprs * gprs, // input/output
227                                                   char * modrm_instr,       // input
228                                                   int * offset,             // output
229                                                   addr_t * first_operand,   // output
230                                                   addr_t * second_operand,  // output
231                                                   reg_size_t reg_size) {    // input
232   
233     struct modrm_byte * modrm = (struct modrm_byte *)modrm_instr;
234     addr_t base_addr = 0;
235     modrm_mode_t mod_mode = 0;
236     v3_operand_type_t addr_type = INVALID_OPERAND;
237     char * instr_cursor = modrm_instr;
238
239     //  PrintDebug("ModRM mod=%d\n", modrm->mod);
240
241     instr_cursor += 1;
242
243     if (modrm->mod == 3) {
244         mod_mode = REG;
245         addr_type = REG_OPERAND;
246         //PrintDebug("first operand = Register (RM=%d)\n",modrm->rm);
247
248         *first_operand = decode_register(gprs, modrm->rm, reg_size);
249
250     } else {
251
252         addr_type = MEM_OPERAND;
253
254         if (modrm->mod == 0) {
255             mod_mode = DISP0;
256         } else if (modrm->mod == 1) {
257             mod_mode = DISP8;
258         } else if (modrm->mod == 2) {
259             mod_mode = DISP16;
260         }
261
262         switch (modrm->rm) {
263             case 0:
264                 base_addr = gprs->rbx + gprs->rsi;
265                 break;
266             case 1:
267                 base_addr = gprs->rbx + gprs->rdi;
268                 break;
269             case 2:
270                 base_addr = gprs->rbp + gprs->rsi;
271                 break;
272             case 3:
273                 base_addr = gprs->rbp + gprs->rdi;
274                 break;
275             case 4:
276                 base_addr = gprs->rsi;
277                 break;
278             case 5:
279                 base_addr = gprs->rdi;
280                 break;
281             case 6:
282                 if (modrm->mod == 0) {
283                     base_addr = 0;
284                     mod_mode = DISP16;
285                 } else {
286                     base_addr = gprs->rbp;
287                 }
288                 break;
289             case 7:
290                 base_addr = gprs->rbx;
291                 break;
292         }
293
294
295
296         if (mod_mode == DISP8) {
297             base_addr += (uchar_t)*(instr_cursor);
298             instr_cursor += 1;
299         } else if (mod_mode == DISP16) {
300             base_addr += (ushort_t)*(instr_cursor);
301             instr_cursor += 2;
302         }
303     
304         *first_operand = base_addr;
305     }
306
307     *offset +=  (instr_cursor - modrm_instr);
308     *second_operand = decode_register(gprs, modrm->reg, reg_size);
309
310     return addr_type;
311 }
312
313
314
315 static inline v3_operand_type_t decode_operands32(struct v3_gprs * gprs, // input/output
316                                                   uchar_t * modrm_instr,       // input
317                                                   int * offset,             // output
318                                                   addr_t * first_operand,   // output
319                                                   addr_t * second_operand,  // output
320                                                   reg_size_t reg_size) {    // input
321   
322     uchar_t * instr_cursor = modrm_instr;
323     struct modrm_byte * modrm = (struct modrm_byte *)modrm_instr;
324     addr_t base_addr = 0;
325     modrm_mode_t mod_mode = 0;
326     uint_t has_sib_byte = 0;
327     v3_operand_type_t addr_type = INVALID_OPERAND;
328
329
330
331     instr_cursor += 1;
332
333     if (modrm->mod == 3) {
334         mod_mode = REG;
335         addr_type = REG_OPERAND;
336     
337         //    PrintDebug("first operand = Register (RM=%d)\n",modrm->rm);
338
339         *first_operand = decode_register(gprs, modrm->rm, reg_size);
340
341     } else {
342
343         addr_type = MEM_OPERAND;
344
345         if (modrm->mod == 0) {
346             mod_mode = DISP0;
347         } else if (modrm->mod == 1) {
348             mod_mode = DISP8;
349         } else if (modrm->mod == 2) {
350             mod_mode = DISP32;
351         }
352     
353         switch (modrm->rm) {
354             case 0:
355                 base_addr = gprs->rax;
356                 break;
357             case 1:
358                 base_addr = gprs->rcx;
359                 break;
360             case 2:
361                 base_addr = gprs->rdx;
362                 break;
363             case 3:
364                 base_addr = gprs->rbx;
365                 break;
366             case 4:
367                 has_sib_byte = 1;
368                 break;
369             case 5:
370                 if (modrm->mod == 0) {
371                     base_addr = 0;
372                     mod_mode = DISP32;
373                 } else {
374                     base_addr = gprs->rbp;
375                 }
376                 break;
377             case 6:
378                 base_addr = gprs->rsi;
379                 break;
380             case 7:
381                 base_addr = gprs->rdi;
382                 break;
383         }
384
385         if (has_sib_byte) {
386             instr_cursor += 1;
387             struct sib_byte * sib = (struct sib_byte *)(instr_cursor);
388             int scale = 1;
389
390             instr_cursor += 1;
391
392
393             if (sib->scale == 1) {
394                 scale = 2;
395             } else if (sib->scale == 2) {
396                 scale = 4;
397             } else if (sib->scale == 3) {
398                 scale = 8;
399             }
400
401
402             switch (sib->index) {
403                 case 0:
404                     base_addr = gprs->rax;
405                     break;
406                 case 1:
407                     base_addr = gprs->rcx;
408                     break;
409                 case 2:
410                     base_addr = gprs->rdx;
411                     break;
412                 case 3:
413                     base_addr = gprs->rbx;
414                     break;
415                 case 4:
416                     base_addr = 0;
417                     break;
418                 case 5:
419                     base_addr = gprs->rbp;
420                     break;
421                 case 6:
422                     base_addr = gprs->rsi;
423                     break;
424                 case 7:
425                     base_addr = gprs->rdi;
426                     break;
427             }
428
429             base_addr *= scale;
430
431
432             switch (sib->base) {
433                 case 0:
434                     base_addr += gprs->rax;
435                     break;
436                 case 1:
437                     base_addr += gprs->rcx;
438                     break;
439                 case 2:
440                     base_addr += gprs->rdx;
441                     break;
442                 case 3:
443                     base_addr += gprs->rbx;
444                     break;
445                 case 4:
446                     base_addr += gprs->rsp;
447                     break;
448                 case 5:
449                     if (modrm->mod != 0) {
450                         base_addr += gprs->rbp;
451                     }
452                     break;
453                 case 6:
454                     base_addr += gprs->rsi;
455                     break;
456                 case 7:
457                     base_addr += gprs->rdi;
458                     break;
459             }
460
461         } 
462
463
464         if (mod_mode == DISP8) {
465             base_addr += (uchar_t)*(instr_cursor);
466             instr_cursor += 1;
467         } else if (mod_mode == DISP32) {
468             base_addr += (uint_t)*(instr_cursor);
469             instr_cursor += 4;
470         }
471     
472
473         *first_operand = base_addr;
474     }
475
476     *offset += (instr_cursor - modrm_instr);
477
478     *second_operand = decode_register(gprs, modrm->reg, reg_size);
479
480     return addr_type;
481 }
482
483
484
485 static inline op_form_t op_code_to_form_0f(uint8_t * instr) {
486     switch (instr[1]) {
487         case 0x01: {
488             struct modrm_byte * modrm = (struct modrm_byte *)&(instr[2]);
489
490             switch (modrm->reg) {
491                 case 4:
492                     return SMSW;
493                 case 6:
494                     return LMSW;
495                 case 7:
496                     return INVLPG;
497                 default:
498                     return INVALID_INSTR;
499             }
500         }
501
502         case 0x06:
503             return CLTS;
504         case 0x20:
505             return MOV_CR2;
506         case 0x21:
507             return MOV_DR2;
508
509         case 0x22:
510             return MOV_2CR;
511         case 0x23:
512             return MOV_2DR;
513
514         case 0x90:
515             return SETO;
516         case 0x91:
517             return SETNO;
518         case 0x92:
519             return SETB;
520         case 0x93:
521             return SETNB;
522         case 0x94:
523             return SETZ;
524         case 0x95:
525             return SETNZ;
526         case 0x96:
527             return SETBE;
528         case 0x97:
529             return SETNBE;
530         case 0x98:
531             return SETS;
532         case 0x99:
533             return SETNS;
534         case 0x9a:
535             return SETP;
536         case 0x9b:
537             return SETNP;
538         case 0x9c:
539             return SETL;
540         case 0x9d:
541             return SETNL;
542         case 0x9e:
543             return SETLE;
544         case 0x9f:
545             return SETNLE;
546
547         case 0xb6:
548             return MOVZX_8;
549         case 0xb7:
550             return MOVZX;
551
552         case 0xbe:
553             return MOVSX_8;
554         case 0xbf:
555             return MOVSX;
556             
557
558         default:
559             return INVALID_INSTR;
560     }
561 }
562
563
564 static op_form_t op_code_to_form(uint8_t * instr) {
565     switch (instr[0]) {
566         case 0x00:
567             return ADD_2MEM_8;
568         case 0x01:
569             return ADD_2MEM;
570         case 0x02:
571             return ADD_MEM2_8;
572         case 0x03:
573             return ADD_MEM2;
574
575         case 0x08:
576             return OR_2MEM_8;
577         case 0x09:
578             return OR_2MEM;
579         case 0x0a:
580             return OR_MEM2_8;
581         case 0x0b:
582             return OR_MEM2;
583
584
585         case 0x0f:
586             return op_code_to_form_0f(instr);
587
588         case 0x10:
589             return ADC_2MEM_8;
590         case 0x11:
591             return ADC_2MEM;
592         case 0x12:
593             return ADC_MEM2_8;
594         case 0x13:
595             return ADC_MEM2;
596
597         case 0x20:
598             return AND_2MEM_8; 
599         case 0x21:
600             return AND_2MEM;
601         case 0x22:
602             return AND_MEM2_8;
603         case 0x23:
604             return AND_MEM2;
605
606         case 0x28:
607             return SUB_2MEM_8;
608         case 0x29:
609             return SUB_2MEM;
610         case 0x2a:
611             return SUB_MEM2_8;
612         case 0x2b:
613             return SUB_MEM2;
614
615
616         case 0x30:
617             return XOR_2MEM_8;
618         case 0x31:
619             return XOR_2MEM;
620         case 0x32:
621             return XOR_MEM2_8;
622         case 0x33:
623             return XOR_MEM2;
624
625         case 0x80:{
626             struct modrm_byte * modrm = (struct modrm_byte *)&(instr[1]);
627
628             switch (modrm->reg) {
629                 case 0:
630                     return ADD_IMM2_8;
631                 case 1:
632                     return OR_IMM2_8;
633                 case 2:
634                     return ADC_IMM2_8;
635                 case 4:
636                     return AND_IMM2_8;
637                 case 5:
638                     return SUB_IMM2_8;
639                 case 6:
640                     return XOR_IMM2_8;
641                 default:
642                     return INVALID_INSTR;
643             }
644         }
645         case 0x81: {
646             struct modrm_byte * modrm = (struct modrm_byte *)&(instr[1]);
647             
648             switch (modrm->reg) {
649                 case 0:
650                     return ADD_IMM2;
651                 case 1:
652                     return OR_IMM2;
653                 case 2:
654                     return ADC_IMM2;
655                 case 4:
656                     return AND_IMM2;
657                 case 5:
658                     return SUB_IMM2;
659                 case 6:
660                     return XOR_IMM2;
661                 default:
662                     return INVALID_INSTR;
663             }
664         }
665         case 0x83: {
666             struct modrm_byte * modrm = (struct modrm_byte *)&(instr[1]);
667
668             switch (modrm->reg) {
669                 case 0:
670                     return ADD_IMM2SX_8;
671                 case 1:
672                     return OR_IMM2SX_8;
673                 case 2:
674                     return ADC_IMM2SX_8;
675                 case 4:
676                     return AND_IMM2SX_8;
677                 case 5:
678                     return SUB_IMM2SX_8;
679                 case 6:
680                     return XOR_IMM2SX_8;
681                 default:
682                     return INVALID_INSTR;
683             }
684         }
685
686         case 0x86:
687             return XCHG_8;
688         case 0x87:
689             return XCHG;
690         case 0x88:
691             return MOV_2GPR_8;
692         case 0x89:
693             return MOV_2GPR;
694         case 0x8a:
695             return MOV_GPR2_8;
696         case 0x8b:
697             return MOV_GPR2;
698             
699         case 0x8c:
700             return MOV_SR2;
701         case 0x8e:
702             return MOV_2SR;
703
704
705         case 0x9c:
706             return PUSHF;
707         case 0x9d:
708             return POPF;
709
710         case 0xa0:
711             return MOV_MEM2AL_8;
712         case 0xa1:
713             return MOV_MEM2AX;
714         case 0xa2:
715             return MOV_AL2MEM_8;
716         case 0xa3:
717             return MOV_AX2MEM;
718
719         case 0xa4:
720             return MOVS_8;
721         case 0xa5:
722             return MOVS;
723
724         case 0xaa:
725             return STOS_8;
726         case 0xab:
727             return STOS;
728
729         case 0xc6:
730             return MOV_IMM2_8;
731         case 0xc7:
732             return MOV_IMM2;
733
734         case 0xf4:
735             return HLT;
736
737
738         case 0xf6: {
739             struct modrm_byte * modrm = (struct modrm_byte *)&(instr[1]);
740
741             switch (modrm->reg) {
742                 case 2:
743                     return NOT_8;
744                 case 3:
745                     return NEG_8;
746                 default:
747                     return INVALID_INSTR;
748             }
749         }
750         case 0xf7: {
751             struct modrm_byte * modrm = (struct modrm_byte *)&(instr[1]);
752
753             switch (modrm->reg) {
754                 case 2:
755                     return NOT;
756                 case 3:
757                     return NEG;
758                 default:
759                     return INVALID_INSTR;
760             }
761         }
762             
763
764         case 0xfe: {
765             struct modrm_byte * modrm = (struct modrm_byte *)&(instr[1]);
766
767             switch (modrm->reg) {
768                 case 0:
769                     return INC_8;
770                 case 1:
771                     return DEC_8;
772                 default:
773                     return INVALID_INSTR;
774             }
775         }
776
777         case 0xff: {
778             struct modrm_byte * modrm = (struct modrm_byte *)&(instr[1]);
779
780             switch (modrm->reg) {
781                 case 0:
782                     return INC;
783                 case 1:
784                     return DEC;
785                 default:
786                     return INVALID_INSTR;
787             }
788         }
789
790         default:
791             return INVALID_INSTR;
792     }
793 }
794
795 int v3_disasm(struct guest_info * info, void *instr_ptr, addr_t * rip, int mark) {
796     return 0;
797 }
798
799
800
801 int v3_init_decoder(struct guest_info * core) { 
802     return 0;
803 }
804
805
806 int v3_deinit_decoder(struct guest_info * core) {
807     return 0;
808 }
809
810
811 int v3_encode(struct guest_info * info, struct x86_instr * instr, char * instr_buf) {
812     return 0;
813 }
814
815 int v3_decode(struct guest_info * info, addr_t instr_ptr, struct x86_instr * instr) {
816     op_code_to_form((void *)instr_ptr);
817
818     return 0;
819 }