CACAO
patcher.cpp
Go to the documentation of this file.
1 /* src/vm/jit/alpha/patcher.cpp - Alpha code patching functions
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 
26 #include "config.h"
27 
28 #include <cassert>
29 
30 #include "vm/types.hpp"
31 
32 #include "vm/jit/alpha/md.hpp"
33 
34 #include "mm/memory.hpp"
35 
36 #include "native/native.hpp"
37 
38 #include "vm/jit/builtin.hpp"
39 #include "vm/class.hpp"
40 #include "vm/field.hpp"
41 #include "vm/initialize.hpp"
42 #include "vm/options.hpp"
43 #include "vm/references.hpp"
44 #include "vm/resolve.hpp"
45 
46 #include "vm/jit/asmpart.hpp"
48 #include "vm/jit/methodheader.hpp"
49 
50 
51 /* patcher_patch_code **********************************************************
52 
53  Just patches back the original machine code.
54 
55 *******************************************************************************/
56 
58 {
59  // Patch back original code.
60  *((uint32_t*) pr->mpc) = pr->mcode;
61 
62  // Synchronize instruction cache.
63  md_icacheflush(NULL, 0);
64 }
65 
66 
67 /* patcher_resolve_classref_to_classinfo ***************************************
68 
69  ACONST:
70 
71  <patched call postition>
72  a61bff80 ldq a0,-128(pv)
73 
74  MULTIANEWARRAY:
75 
76  <patched call position>
77  a63bff80 ldq a1,-128(pv)
78  47de0412 mov sp,a2
79  a77bff78 ldq pv,-136(pv)
80  6b5b4000 jsr (pv)
81 
82  ARRAYCHECKCAST:
83 
84  <patched call position>
85  a63bfe60 ldq a1,-416(pv)
86  a77bfe58 ldq pv,-424(pv)
87  6b5b4000 jsr (pv)
88 
89 *******************************************************************************/
90 
92 {
94  u1 *datap;
95  classinfo *c;
96 
97  /* get stuff from the stack */
98 
99  cr = (constant_classref *) pr->ref;
100  datap = (u1 *) pr->datap;
101 
102  /* get the classinfo */
103 
104  if (!(c = resolve_classref_eager(cr)))
105  return false;
106 
107  /* patch the classinfo pointer */
108 
109  *((ptrint *) datap) = (ptrint) c;
110 
111  // Patch back the original code.
112  patcher_patch_code(pr);
113 
114  return true;
115 }
116 
117 
118 /* patcher_resolve_classref_to_vftbl *******************************************
119 
120  CHECKCAST (class):
121  INSTANCEOF (class):
122 
123  <patched call position>
124  a7940000 ldq at,0(a4)
125  a7bbff28 ldq gp,-216(pv)
126 
127 *******************************************************************************/
128 
130 {
131  constant_classref *cr;
132  u1 *datap;
133  classinfo *c;
134 
135  /* get stuff from the stack */
136 
137  cr = (constant_classref *) pr->ref;
138  datap = (u1 *) pr->datap;
139 
140  /* get the fieldinfo */
141 
142  if (!(c = resolve_classref_eager(cr)))
143  return false;
144 
145  /* patch super class' vftbl */
146 
147  *((ptrint *) datap) = (ptrint) c->vftbl;
148 
149  // Patch back the original code.
150  patcher_patch_code(pr);
151 
152  return true;
153 }
154 
155 
156 /* patcher_resolve_classref_to_flags *******************************************
157 
158  CHECKCAST/INSTANCEOF:
159 
160  <patched call position>
161 
162 *******************************************************************************/
163 
165 {
166  constant_classref *cr;
167  u1 *datap;
168  classinfo *c;
169 
170  /* get stuff from the stack */
171 
172  cr = (constant_classref *) pr->ref;
173  datap = (u1 *) pr->datap;
174 
175  /* get the fieldinfo */
176 
177  if (!(c = resolve_classref_eager(cr)))
178  return false;
179 
180  /* patch class flags */
181 
182  *((s4 *) datap) = (s4) c->flags;
183 
184  // Patch back the original code.
185  patcher_patch_code(pr);
186 
187  return true;
188 }
189 
190 
191 /* patcher_get_putstatic *******************************************************
192 
193  Machine code:
194 
195  <patched call position>
196  a73bff98 ldq t11,-104(pv)
197  a2590000 ldl a2,0(t11)
198 
199 *******************************************************************************/
200 
202 {
203  unresolved_field *uf;
204  u1 *datap;
205  fieldinfo *fi;
206 
207  /* get stuff from the stack */
208 
209  uf = (unresolved_field *) pr->ref;
210  datap = (u1 *) pr->datap;
211 
212  /* get the fieldinfo */
213 
214  if (!(fi = resolve_field_eager(uf)))
215  return false;
216 
217  /* check if the field's class is initialized */
218 
219  if (!(fi->clazz->state & CLASS_INITIALIZED))
220  if (!initialize_class(fi->clazz))
221  return false;
222 
223  /* patch the field value's address */
224 
225  *((intptr_t *) datap) = (intptr_t) fi->value;
226 
227  // Patch back the original code.
228  patcher_patch_code(pr);
229 
230  return true;
231 }
232 
233 
234 /* patcher_get_putfield ********************************************************
235 
236  Machine code:
237 
238  <patched call position>
239  a2af0020 ldl a5,32(s6)
240 
241 *******************************************************************************/
242 
244 {
245  unresolved_field *uf;
246  fieldinfo *fi;
247 
248  uf = (unresolved_field *) pr->ref;
249 
250  /* get the fieldinfo */
251 
252  if (!(fi = resolve_field_eager(uf)))
253  return false;
254 
255  /* patch the field's offset into the instruction */
256 
257  pr->mcode |= (s2) (fi->offset & 0x0000ffff);
258 
259  // Patch back the original code.
260  patcher_patch_code(pr);
261 
262  return true;
263 }
264 
265 
266 /* patcher_invokestatic_special ************************************************
267 
268  Machine code:
269 
270  <patched call position>
271  a77bffa8 ldq pv,-88(pv)
272  6b5b4000 jsr (pv)
273 
274 ******************************************************************************/
275 
277 {
278  unresolved_method *um;
279  u1 *datap;
280  methodinfo *m;
281 
282  /* get stuff from the stack */
283 
284  um = (unresolved_method *) pr->ref;
285  datap = (u1 *) pr->datap;
286 
287  /* get the fieldinfo */
288 
289  if (!(m = resolve_method_eager(um)))
290  return false;
291 
292  /* patch stubroutine */
293 
294  *((ptrint *) datap) = (ptrint) m->stubroutine;
295 
296  // Patch back the original code.
297  patcher_patch_code(pr);
298 
299  return true;
300 }
301 
302 
303 /* patcher_invokevirtual *******************************************************
304 
305  Machine code:
306 
307  <patched call position>
308  a7900000 ldq at,0(a0)
309  a77c0100 ldq pv,256(at)
310  6b5b4000 jsr (pv)
311 
312 *******************************************************************************/
313 
315 {
316  u1 *ra;
317  unresolved_method *um;
318  methodinfo *m;
319 
320  /* get stuff from the stack */
321 
322  ra = (u1 *) pr->mpc;
323  um = (unresolved_method *) pr->ref;
324 
325  /* get the fieldinfo */
326 
327  if (!(m = resolve_method_eager(um)))
328  return false;
329 
330  /* patch vftbl index */
331 
332  *((s4 *) (ra + 4)) |= (s4) ((OFFSET(vftbl_t, table[0]) +
333  sizeof(methodptr) * m->vftblindex) & 0x0000ffff);
334 
335  md_icacheflush(NULL, 0);
336 
337  // Patch back the original code.
338  patcher_patch_code(pr);
339 
340  return true;
341 }
342 
343 
344 /* patcher_invokeinterface *****************************************************
345 
346  Machine code:
347 
348  <patched call position>
349  a7900000 ldq at,0(a0)
350  a79cffa0 ldq at,-96(at)
351  a77c0018 ldq pv,24(at)
352  6b5b4000 jsr (pv)
353 
354 *******************************************************************************/
355 
357 {
358  u1 *ra;
359  unresolved_method *um;
360  methodinfo *m;
361 
362  /* get stuff from the stack */
363 
364  ra = (u1 *) pr->mpc;
365  um = (unresolved_method *) pr->ref;
366 
367  /* get the fieldinfo */
368 
369  if (!(m = resolve_method_eager(um)))
370  return false;
371 
372  /* patch interfacetable index */
373 
374  *((s4 *) (ra + 4)) |= (s4) ((OFFSET(vftbl_t, interfacetable[0]) -
375  sizeof(methodptr*) * m->clazz->index) & 0x0000ffff);
376 
377  /* patch method offset */
378 
379  *((s4 *) (ra + 4 + 4)) |=
380  (s4) ((sizeof(methodptr) * (m - m->clazz->methods)) & 0x0000ffff);
381 
382  md_icacheflush(NULL, 0);
383 
384  // Patch back the original code.
385  patcher_patch_code(pr);
386 
387  return true;
388 }
389 
390 
391 /* patcher_checkcast_interface *************************************************
392 
393  Machine code:
394 
395  <patched call position>
396  a78e0000 ldq at,0(s5)
397  a3bc001c ldl gp,28(at)
398  23bdfffd lda gp,-3(gp)
399  efa0002e ble gp,0x00000200002bf6b0
400  a7bcffe8 ldq gp,-24(at)
401 
402 *******************************************************************************/
403 
405 {
406  u1 *ra;
407  constant_classref *cr;
408  classinfo *c;
409 
410  /* get stuff from the stack */
411 
412  ra = (u1 *) pr->mpc;
413  cr = (constant_classref *) pr->ref;
414 
415  /* get the fieldinfo */
416 
417  if (!(c = resolve_classref_eager(cr)))
418  return false;
419 
420  /* patch super class index */
421 
422  *((s4 *) (ra + 2 * 4)) |= (s4) (-(c->index) & 0x0000ffff);
423 
424  *((s4 *) (ra + 5 * 4)) |= (s4) ((OFFSET(vftbl_t, interfacetable[0]) -
425  c->index * sizeof(methodptr*)) & 0x0000ffff);
426 
427  md_icacheflush(NULL, 0);
428 
429  // Patch back the original code.
430  patcher_patch_code(pr);
431 
432  return true;
433 }
434 
435 
436 /* patcher_instanceof_interface ************************************************
437 
438  Machine code:
439 
440  <patched call position>
441  a78e0000 ldq at,0(s5)
442  a3bc001c ldl gp,28(at)
443  23bdfffd lda gp,-3(gp)
444  efa0002e ble gp,0x00000200002bf6b0
445  a7bcffe8 ldq gp,-24(at)
446 
447 *******************************************************************************/
448 
450 {
451  u1 *ra;
452  constant_classref *cr;
453  classinfo *c;
454 
455  /* get stuff from the stack */
456 
457  ra = (u1 *) pr->mpc;
458  cr = (constant_classref *) pr->ref;
459 
460  /* get the fieldinfo */
461 
462  if (!(c = resolve_classref_eager(cr)))
463  return false;
464 
465  /* patch super class index */
466 
467  *((s4 *) (ra + 2 * 4)) |= (s4) (-(c->index) & 0x0000ffff);
468 
469  *((s4 *) (ra + 4 * 4)) |= (s4) ((OFFSET(vftbl_t, interfacetable[0]) -
470  c->index * sizeof(methodptr*)) & 0x0000ffff);
471 
472  md_icacheflush(NULL, 0);
473 
474  // Patch back the original code.
475  patcher_patch_code(pr);
476 
477  return true;
478 }
479 
480 
481 /*
482  * These are local overrides for various environment variables in Emacs.
483  * Please do not remove this and leave it at the end of the file, where
484  * Emacs will automagically detect them.
485  * ---------------------------------------------------------------------
486  * Local variables:
487  * mode: c++
488  * indent-tabs-mode: t
489  * c-basic-offset: 4
490  * tab-width: 4
491  * End:
492  * vim:noexpandtab:sw=4:ts=4:
493  */
bool patcher_invokestatic_special(patchref_t *pr)
Definition: patcher.cpp:392
bool patcher_get_putstatic(patchref_t *pr)
Definition: patcher.cpp:264
#define ra
Definition: md-asm.hpp:62
bool patcher_resolve_classref_to_classinfo(patchref_t *pr)
Definition: patcher.cpp:148
methodinfo * methods
Definition: class.hpp:113
bool patcher_invokeinterface(patchref_t *pr)
Definition: patcher.cpp:477
s4 state
Definition: class.hpp:115
uint8_t u1
Definition: types.hpp:40
u1 * methodptr
Definition: global.hpp:40
u1 * stubroutine
Definition: method.hpp:102
s4 vftblindex
Definition: method.hpp:81
int32_t offset
Definition: field.hpp:66
classinfo * clazz
Definition: method.hpp:80
void patcher_patch_code(patchref_t *pr)
Definition: patcher.cpp:114
bool patcher_invokevirtual(patchref_t *pr)
Definition: patcher.cpp:433
imm_union * value
Definition: field.hpp:67
bool patcher_resolve_classref_to_flags(patchref_t *pr)
Definition: patcher.cpp:225
bool patcher_checkcast_interface(patchref_t *pr)
Definition: patcher.cpp:526
s4 flags
Definition: class.hpp:90
int32_t s4
Definition: types.hpp:45
classinfo * clazz
Definition: field.hpp:55
s4 index
Definition: class.hpp:116
bool initialize_class(classinfo *c)
Definition: initialize.cpp:110
bool patcher_get_putfield(patchref_t *pr)
Definition: patcher.cpp:308
vftbl_t * vftbl
Definition: class.hpp:121
fieldinfo * resolve_field_eager(unresolved_field *ref)
Definition: resolve.cpp:1497
methodinfo * resolve_method_eager(unresolved_method *ref)
Definition: resolve.cpp:2236
uintptr_t datap
uint32_t mcode
int16_t s2
Definition: types.hpp:42
classinfo * resolve_classref_eager(constant_classref *ref)
Definition: resolve.cpp:961
uintptr_t ptrint
Definition: types.hpp:54
static void md_icacheflush(void *addr, int nbytes)
Definition: md.hpp:151
uintptr_t mpc
#define OFFSET(s, el)
Definition: memory.hpp:90
bool patcher_resolve_classref_to_vftbl(patchref_t *pr)
Definition: patcher.cpp:188
bool patcher_instanceof_interface(patchref_t *pr)
Definition: patcher.cpp:572