]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/plr/server/src/emulation
update
[l4.git] / l4 / pkg / plr / server / src / emulation
1 // vim: ft=cpp
2 #pragma once
3
4 /*
5  * emulation --
6  *
7  *     Basic definition of an instruction emulator. Used
8  *     by the framework to emulate memory write instructions.
9  *
10  * (c) 2011-2013 Björn Döbel <doebel@os.inf.tu-dresden.de>,
11  *     economic rights: Technische Universität Dresden (Germany)
12  * This file is part of TUD:OS and distributed under the terms of the
13  * GNU General Public License 2.
14  * Please see the COPYING-GPL-2 file for details.
15  */
16
17 #include <l4/vcpu/vcpu>
18 #include "log"
19
20 namespace Romain {
21 /*
22  * Address translation abstraction.
23  */
24 struct AddressTranslator
25 {
26         virtual l4_addr_t translate(l4_addr_t orig) const = 0;
27         virtual ~AddressTranslator() {}
28 };
29
30 struct IdentityTranslator : public AddressTranslator
31 {
32         virtual l4_addr_t translate(l4_addr_t orig) const { return orig; }
33 };
34
35 }
36 //#include "app_loading"
37
38 #include <libudis86/types.h>
39 #include <libudis86/extern.h>
40 #include <libudis86/itab.h>
41
42 namespace Romain {
43
44 enum X86Eflags {
45         CarryFlag     =   0x1,
46         ParityFlag    =   0x4,
47         AuxCarryFlag  =  0x10,
48         ZeroFlag      =  0x40,
49         SignFlag      =  0x80,
50         TrapFlag      = 0x100,
51         InterruptFlag = 0x200,
52         DirectionFlag = 0x400,
53         OverflowFlag  = 0x800,
54 };
55
56 class Emulator_base
57 {
58         protected:
59                 enum {
60                         UD_MAX_OPERANDS = 3,
61                 };
62                 L4vcpu::Vcpu           *_vcpu;
63                 Romain::AddressTranslator const * _translator;
64                 l4_addr_t               _local_ip;   // XXX: abstraction fault
65                 ud_t                    _ud;
66
67                 void value_to_operand(l4_umword_t val, ud_operand *op);
68                 int  offset_from_operand(ud_operand *op);
69
70                 l4_umword_t register_to_value(ud_type op);
71                 void value_to_register(l4_umword_t val, ud_type op);
72
73         public:
74                 virtual l4_addr_t ip()    { return _vcpu->r()->ip; }
75                 l4_addr_t         local() { return _local_ip; }
76                 l4_umword_t       ilen()  { return ud_insn_len(&_ud); }
77
78         protected:
79                 l4_umword_t operand_to_value(ud_operand *op);
80                 void write_target(l4_addr_t address, l4_umword_t value, l4_size_t size)
81                 {
82                         switch(size) {
83                                 case 8:
84                                         *(unsigned char*)address = (unsigned char)value;
85                                         break;
86                                 case 16:
87                                         *(unsigned short*)address = (unsigned short)value;
88                                         break;
89                                 case 32:
90                                         *(l4_umword_t*)address = value;
91                                         break;
92                                 // XXX: case 64:
93                                 //     break;
94                                 default:
95                                         ERROR() << std::hex << address << ", "
96                                                 << value << ", " << size << "\n";
97                                         break;
98                         }
99                 }
100                 void init_ud();
101
102         public:
103                 Emulator_base(L4vcpu::Vcpu *, Romain::AddressTranslator const *);
104 #if 1
105                 Emulator_base() // XXX: needed?
106                         : _vcpu(0), _translator(new IdentityTranslator()), _local_ip(0)
107                 {}
108 #endif
109                 void print_instruction();
110 };
111
112
113 class InstructionPrinter : public Emulator_base
114 {
115         l4_addr_t _remote;
116         public:
117                 InstructionPrinter(l4_addr_t local, l4_addr_t remote)
118                         : _remote(remote)
119                 {
120                         _local_ip = local;
121                         init_ud();
122                         print_instruction();
123                 }
124
125                 virtual l4_addr_t ip() { return _remote; }
126 };
127
128
129 class WriteEmulator : public Emulator_base
130 {
131         protected:
132                 void handle_push();
133                 void handle_call();
134                 void handle_mov();
135                 void handle_movsd();
136                 void handle_movsb();
137                 void handle_stos();
138
139                 enum ArithmeticOperations {
140                         ADD,
141                         SUB,
142                         MULT,
143                         DIV,
144                         MOD,
145                         DEC,
146                 };
147
148                 void handle_arithmetics(ArithmeticOperations o);
149
150         public:
151                 WriteEmulator(L4vcpu::Vcpu *vcpu,
152                               Romain::AddressTranslator const *trans)
153                         : Emulator_base(vcpu, trans)
154                 {
155                 }
156
157                 void emulate(/*l4_addr_t remote_addr*/);
158 };
159
160 }