Line data Source code
1 : /* src/vm/jit/PatcherNew.hpp - Patcher class
2 :
3 : Copyright (C) 1996-2013
4 : CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
5 :
6 : This file is part of CACAO.
7 :
8 : This program is free software; you can redistribute it and/or
9 : modify it under the terms of the GNU General Public License as
10 : published by the Free Software Foundation; either version 2, or (at
11 : your option) any later version.
12 :
13 : This program is distributed in the hope that it will be useful, but
14 : WITHOUT ANY WARRANTY; without even the implied warranty of
15 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 : General Public License for more details.
17 :
18 : You should have received a copy of the GNU General Public License
19 : along with this program; if not, write to the Free Software
20 : Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21 : 02110-1301, USA.
22 :
23 : */
24 :
25 : #ifndef _PATCHERNEW_HPP
26 : #define _PATCHERNEW_HPP
27 :
28 : #include "vm/jit/patcher-common.hpp"
29 :
30 : namespace cacao {
31 :
32 : // forward declaration
33 : class OStream;
34 :
35 : /**
36 : * Patcher super class
37 : *
38 : * This class is intended to replace the patchref_t patcher references.
39 : * The goal is to replace function pointers by virtual functions and
40 : * void pointers by member variables. Although we need a vtbl_ptr for
41 : * virtual functions and a smart pointer for list storage this might even
42 : * reduce the overall memory consumption because not all fields of patchref_t
43 : * are needed by all patchers. But the main focus is on encapsulation and
44 : * usability.
45 : *
46 : * @todo Remove/adopt the text above if the legacy patchref_t framework has
47 : * been removed.
48 : */
49 : class Patcher {
50 : private:
51 : bool done;
52 : /**
53 : * This function performs the patching.
54 : */
55 : virtual bool patch_impl() = 0;
56 : public:
57 : Patcher();
58 : virtual ~Patcher();
59 :
60 : /**
61 : * This a wrapper to set the done flag.
62 : */
63 71142 : bool patch() {
64 71142 : if (patch_impl()) {
65 71129 : done = true;
66 71129 : return true;
67 : }
68 13 : return false;
69 : }
70 : /**
71 : * get the absolute position in code segment
72 : *
73 : * @deprecated
74 : */
75 : virtual uintptr_t get_mpc() const = 0;
76 : /**
77 : * Generates the code for the patcher traps.
78 : */
79 : virtual void emit() = 0;
80 : /**
81 : * reposition to another base
82 : */
83 : virtual void reposition(intptr_t base) = 0;
84 : /**
85 : * Check already patched
86 : *
87 : * In contrast to check_is_patched this method simply
88 : * queries a boolean variable whereas check_is_patched
89 : * inspects to machine code.
90 : *
91 : * @see check_is_patched
92 : */
93 71146 : bool is_patched() const {
94 71146 : return done;
95 : }
96 : /**
97 : * Check if the patcher is already patched.
98 : *
99 : * This is done by comparing the machine instruction.
100 : *
101 : * @return true if patched, false otherwise.
102 : * @see is_patched
103 : */
104 : virtual bool check_is_patched() const = 0;
105 : /**
106 : * print patcher information
107 : */
108 : virtual const char* get_name() const;
109 : /**
110 : * print patcher information
111 : */
112 : virtual OStream& print(OStream &OS) const;
113 : };
114 :
115 0 : class LegacyPatcher : public Patcher {
116 : private:
117 : jitdata *jd;
118 : patchref_t pr;
119 :
120 : /**
121 : * Call the legacy patching function
122 : */
123 71142 : virtual bool patch_impl() {
124 : // define the patcher function
125 : bool (*patcher_function)(patchref_t *);
126 : // cast the passed function to a patcher function
127 71142 : patcher_function = (bool (*)(patchref_t *)) (ptrint) pr.patcher;
128 :
129 71142 : return (patcher_function)(&pr);
130 : }
131 :
132 : public:
133 :
134 142524 : LegacyPatcher(jitdata *jd, const patchref_t &pr)
135 142524 : : Patcher(), jd(jd), pr(pr) {}
136 :
137 : /**
138 : * return the raw resource
139 : */
140 142524 : patchref_t* get() {
141 142524 : return ≺
142 : }
143 :
144 5755676 : virtual uintptr_t get_mpc() const {
145 5755676 : return pr.mpc;
146 : }
147 : virtual void emit();
148 142524 : virtual void reposition(intptr_t base) {
149 142524 : pr.mpc += base;
150 142524 : pr.datap = (intptr_t) (pr.disp + base);
151 142524 : }
152 : /**
153 : * Check if the patcher is already patched.
154 : *
155 : * This is done by comparing the machine instruction.
156 : *
157 : * @return true if patched, false otherwise.
158 : */
159 : virtual bool check_is_patched() const;
160 :
161 : virtual const char* get_name() const;
162 : virtual OStream& print(OStream &OS) const;
163 : };
164 :
165 : /**
166 : * Base class for all (non-legacy) patcher
167 : */
168 0 : class PatcherBase : public Patcher {
169 : private:
170 : uint32_t mcode;
171 : uintptr_t mpc;
172 : public:
173 0 : PatcherBase() : Patcher(), mcode(0), mpc(0) {}
174 : explicit PatcherBase(uintptr_t mpc) : Patcher(), mcode(0), mpc(mpc) {}
175 :
176 0 : virtual void set_mcode(uint32_t mcode) {
177 0 : this->mcode = mcode;
178 0 : }
179 : #if 0
180 : virtual uintptr_t get_mcode() const {
181 : return mcode;
182 : }
183 : #endif
184 0 : virtual uintptr_t get_mpc() const {
185 0 : return mpc;
186 : }
187 0 : virtual void reposition(intptr_t base) {
188 0 : this->mpc += base;
189 0 : }
190 0 : virtual const char* get_name() const {
191 0 : return "PatcherBase";
192 : }
193 : };
194 :
195 0 : class InitializeClassPatcher : public PatcherBase {
196 : private:
197 : classinfo *c;
198 :
199 : virtual bool patch_impl();
200 : public:
201 : virtual void emit();
202 : virtual bool check_is_patched() const;
203 0 : InitializeClassPatcher(classinfo *c) : c(c) {}
204 0 : virtual const char* get_name() const {
205 0 : return "InitializeClassPatcher";
206 : }
207 : };
208 :
209 : } // end namespace cacao
210 :
211 : #endif // _PATCHERNEW_HPP
212 :
213 :
214 : /*
215 : * These are local overrides for various environment variables in Emacs.
216 : * Please do not remove this and leave it at the end of the file, where
217 : * Emacs will automagically detect them.
218 : * ---------------------------------------------------------------------
219 : * Local variables:
220 : * mode: c++
221 : * indent-tabs-mode: t
222 : * c-basic-offset: 4
223 : * tab-width: 4
224 : * End:
225 : * vim:noexpandtab:sw=4:ts=4:
226 : */
|