CACAO
PatcherNew.hpp
Go to the documentation of this file.
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 
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  bool patch() {
64  if (patch_impl()) {
65  done = true;
66  return true;
67  }
68  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  bool is_patched() const {
94  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 class LegacyPatcher : public Patcher {
116 private:
119 
120  /**
121  * Call the legacy patching function
122  */
123  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  patcher_function = (bool (*)(patchref_t *)) (ptrint) pr.patcher;
128 
129  return (patcher_function)(&pr);
130  }
131 
132 public:
133 
135  : Patcher(), jd(jd), pr(pr) {}
136 
137  /**
138  * return the raw resource
139  */
140  patchref_t* get() {
141  return ≺
142  }
143 
144  virtual uintptr_t get_mpc() const {
145  return pr.mpc;
146  }
147  virtual void emit();
148  virtual void reposition(intptr_t base) {
149  pr.mpc += base;
150  pr.datap = (intptr_t) (pr.disp + base);
151  }
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 class PatcherBase : public Patcher {
169 private:
170  uint32_t mcode;
171  uintptr_t mpc;
172 public:
173  PatcherBase() : Patcher(), mcode(0), mpc(0) {}
174  explicit PatcherBase(uintptr_t mpc) : Patcher(), mcode(0), mpc(mpc) {}
175 
176  virtual void set_mcode(uint32_t mcode) {
177  this->mcode = mcode;
178  }
179  #if 0
180  virtual uintptr_t get_mcode() const {
181  return mcode;
182  }
183  #endif
184  virtual uintptr_t get_mpc() const {
185  return mpc;
186  }
187  virtual void reposition(intptr_t base) {
188  this->mpc += base;
189  }
190  virtual const char* get_name() const {
191  return "PatcherBase";
192  }
193 };
194 
196 private:
198 
199  virtual bool patch_impl();
200 public:
201  virtual void emit();
202  virtual bool check_is_patched() const;
204  virtual const char* get_name() const {
205  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  */
virtual bool check_is_patched() const =0
Check if the patcher is already patched.
functionptr patcher
Definition: jit.hpp:126
virtual bool patch_impl()
This function performs the patching.
Definition: PatcherNew.cpp:171
virtual const char * get_name() const
print patcher information
Definition: PatcherNew.cpp:143
virtual OStream & print(OStream &OS) const
print patcher information
Definition: PatcherNew.cpp:156
virtual void emit()=0
Generates the code for the patcher traps.
bool patch()
This a wrapper to set the done flag.
Definition: PatcherNew.hpp:63
virtual void reposition(intptr_t base)
reposition to another base
Definition: PatcherNew.hpp:148
virtual void reposition(intptr_t base)
reposition to another base
Definition: PatcherNew.hpp:187
virtual bool patch_impl()
Call the legacy patching function.
Definition: PatcherNew.hpp:123
virtual void emit()
Generates the code for the patcher traps.
Definition: PatcherNew.cpp:64
virtual uintptr_t get_mpc() const
get the absolute position in code segment
Definition: PatcherNew.hpp:184
virtual uintptr_t get_mpc() const =0
get the absolute position in code segment
virtual bool check_is_patched() const
Definition: PatcherNew.cpp:186
virtual ~Patcher()
Definition: PatcherNew.cpp:41
virtual const char * get_name() const
print patcher information
Definition: PatcherNew.hpp:190
PatcherBase(uintptr_t mpc)
Definition: PatcherNew.hpp:174
Simple stream class for formatted output.
Definition: OStream.hpp:141
virtual void reposition(intptr_t base)=0
reposition to another base
virtual OStream & print(OStream &OS) const
print patcher information
Definition: PatcherNew.cpp:49
InitializeClassPatcher(classinfo *c)
Definition: PatcherNew.hpp:203
virtual bool patch_impl()=0
This function performs the patching.
virtual const char * get_name() const
print patcher information
Definition: PatcherNew.cpp:45
LegacyPatcher(jitdata *jd, const patchref_t &pr)
Definition: PatcherNew.hpp:134
OStream & OS
#define return
bool is_patched() const
Check already patched.
Definition: PatcherNew.hpp:93
uintptr_t datap
virtual void set_mcode(uint32_t mcode)
Definition: PatcherNew.hpp:176
virtual bool check_is_patched() const
Check if the patcher is already patched.
Definition: PatcherNew.cpp:88
virtual uintptr_t get_mpc() const
get the absolute position in code segment
Definition: PatcherNew.hpp:144
Base class for all (non-legacy) patcher.
Definition: PatcherNew.hpp:168
uintptr_t ptrint
Definition: types.hpp:54
virtual const char * get_name() const
print patcher information
Definition: PatcherNew.hpp:204
uintptr_t mpc
Patcher super class.
Definition: PatcherNew.hpp:49