1 /* src/vm/jit/alpha/patcher.c - Alpha code patching functions
3 Copyright (C) 1996-2005, 2006, 2007 R. Grafl, A. Krall, C. Kruegel,
4 C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
5 E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
6 J. Wenninger, Institut f. Computersprachen - TU Wien
8 This file is part of CACAO.
10 This program is free software; you can redistribute it and/or
11 modify it under the terms of the GNU General Public License as
12 published by the Free Software Foundation; either version 2, or (at
13 your option) any later version.
15 This program is distributed in the hope that it will be useful, but
16 WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
25 $Id: patcher.c 8268 2007-08-07 13:24:43Z twisti $
36 #include "mm/memory.h"
38 #include "native/native.h"
40 #include "vm/builtin.h"
41 #include "vm/exceptions.h"
42 #include "vm/initialize.h"
44 #include "vm/jit/asmpart.h"
45 #include "vm/jit/patcher-common.h"
46 #include "vm/jit/md.h"
47 #include "vm/jit/methodheader.h"
48 #include "vm/jit/stacktrace.h"
50 #include "vmcore/class.h"
51 #include "vmcore/field.h"
52 #include "vmcore/options.h"
53 #include "vmcore/references.h"
54 #include "vm/resolve.h"
57 #define PATCH_BACK_ORIGINAL_MCODE \
58 *((u4 *) pr->mpc) = (u4) pr->mcode; \
59 md_icacheflush(NULL, 0);
62 /* patcher_initialize_class ****************************************************
64 Initalizes a given classinfo pointer. This function does not patch
67 *******************************************************************************/
69 bool patcher_initialize_class(patchref_t *pr)
73 /* get stuff from the stack */
75 c = (classinfo *) pr->ref;
77 /* check if the class is initialized */
79 if (!(c->state & CLASS_INITIALIZED))
80 if (!initialize_class(c))
83 PATCH_BACK_ORIGINAL_MCODE;
88 /* patcher_resolve_class *****************************************************
90 Initalizes a given classinfo pointer. This function does not patch
93 *******************************************************************************/
95 #ifdef ENABLE_VERIFIER
96 bool patcher_resolve_class(patchref_t *pr)
100 /* get stuff from the stack */
102 uc = (unresolved_class *) pr->ref;
104 /* resolve the class and check subtype constraints */
106 if (!resolve_class_eager_no_access_check(uc))
109 PATCH_BACK_ORIGINAL_MCODE;
113 #endif /* ENABLE_VERIFIER */
116 /* patcher_resolve_classref_to_classinfo ***************************************
120 <patched call postition>
121 a61bff80 ldq a0,-128(pv)
125 <patched call position>
126 a63bff80 ldq a1,-128(pv)
128 a77bff78 ldq pv,-136(pv)
133 <patched call position>
134 a63bfe60 ldq a1,-416(pv)
135 a77bfe58 ldq pv,-424(pv)
138 *******************************************************************************/
140 bool patcher_resolve_classref_to_classinfo(patchref_t *pr)
142 constant_classref *cr;
146 /* get stuff from the stack */
148 cr = (constant_classref *) pr->ref;
149 datap = (u1 *) pr->datap;
151 /* get the classinfo */
153 if (!(c = resolve_classref_eager(cr)))
156 PATCH_BACK_ORIGINAL_MCODE;
158 /* patch the classinfo pointer */
160 *((ptrint *) datap) = (ptrint) c;
166 /* patcher_resolve_classref_to_vftbl *******************************************
171 <patched call position>
172 a7940000 ldq at,0(a4)
173 a7bbff28 ldq gp,-216(pv)
175 *******************************************************************************/
177 bool patcher_resolve_classref_to_vftbl(patchref_t *pr)
179 constant_classref *cr;
183 /* get stuff from the stack */
185 cr = (constant_classref *) pr->ref;
186 datap = (u1 *) pr->datap;
188 /* get the fieldinfo */
190 if (!(c = resolve_classref_eager(cr)))
193 PATCH_BACK_ORIGINAL_MCODE;
195 /* patch super class' vftbl */
197 *((ptrint *) datap) = (ptrint) c->vftbl;
203 /* patcher_resolve_classref_to_flags *******************************************
205 CHECKCAST/INSTANCEOF:
207 <patched call position>
209 *******************************************************************************/
211 bool patcher_resolve_classref_to_flags(patchref_t *pr)
213 constant_classref *cr;
217 /* get stuff from the stack */
219 cr = (constant_classref *) pr->ref;
220 datap = (u1 *) pr->datap;
222 /* get the fieldinfo */
224 if (!(c = resolve_classref_eager(cr)))
227 PATCH_BACK_ORIGINAL_MCODE;
229 /* patch class flags */
231 *((s4 *) datap) = (s4) c->flags;
237 /* patcher_resolve_native_function *********************************************
241 *******************************************************************************/
243 #if !defined(WITH_STATIC_CLASSPATH)
244 bool patcher_resolve_native_function(patchref_t *pr)
250 /* get stuff from the stack */
252 m = (methodinfo *) pr->ref;
253 datap = (u1 *) pr->datap;
255 /* resolve native function */
257 if (!(f = native_resolve_function(m)))
260 PATCH_BACK_ORIGINAL_MCODE;
262 /* patch native function pointer */
264 *((ptrint *) datap) = (ptrint) f;
268 #endif /* !defined(WITH_STATIC_CLASSPATH) */
271 /* patcher_get_putstatic *******************************************************
275 <patched call position>
276 a73bff98 ldq t11,-104(pv)
277 a2590000 ldl a2,0(t11)
279 *******************************************************************************/
281 bool patcher_get_putstatic(patchref_t *pr)
283 unresolved_field *uf;
287 /* get stuff from the stack */
289 uf = (unresolved_field *) pr->ref;
290 datap = (u1 *) pr->datap;
292 /* get the fieldinfo */
294 if (!(fi = resolve_field_eager(uf)))
297 /* check if the field's class is initialized */
299 if (!(fi->class->state & CLASS_INITIALIZED))
300 if (!initialize_class(fi->class))
303 PATCH_BACK_ORIGINAL_MCODE;
305 /* patch the field value's address */
307 *((intptr_t *) datap) = (intptr_t) fi->value;
313 /* patcher_get_putfield ********************************************************
317 <patched call position>
318 a2af0020 ldl a5,32(s6)
320 *******************************************************************************/
322 bool patcher_get_putfield(patchref_t *pr)
325 unresolved_field *uf;
329 uf = (unresolved_field *) pr->ref;
331 /* get the fieldinfo */
333 if (!(fi = resolve_field_eager(uf)))
336 PATCH_BACK_ORIGINAL_MCODE;
338 /* if we show disassembly, we have to skip the nop */
343 /* patch the field's offset into the instruction */
345 *((u4 *) ra) |= (s2) (fi->offset & 0x0000ffff);
347 md_icacheflush(NULL, 0);
353 /* patcher_invokestatic_special ************************************************
357 <patched call position>
358 a77bffa8 ldq pv,-88(pv)
361 ******************************************************************************/
363 bool patcher_invokestatic_special(patchref_t *pr)
365 unresolved_method *um;
369 /* get stuff from the stack */
371 um = (unresolved_method *) pr->ref;
372 datap = (u1 *) pr->datap;
374 /* get the fieldinfo */
376 if (!(m = resolve_method_eager(um)))
379 PATCH_BACK_ORIGINAL_MCODE;
381 /* patch stubroutine */
383 *((ptrint *) datap) = (ptrint) m->stubroutine;
389 /* patcher_invokevirtual *******************************************************
393 <patched call position>
394 a7900000 ldq at,0(a0)
395 a77c0100 ldq pv,256(at)
398 *******************************************************************************/
400 bool patcher_invokevirtual(patchref_t *pr)
403 unresolved_method *um;
406 /* get stuff from the stack */
409 um = (unresolved_method *) pr->ref;
411 /* get the fieldinfo */
413 if (!(m = resolve_method_eager(um)))
416 PATCH_BACK_ORIGINAL_MCODE;
418 /* if we show disassembly, we have to skip the nop */
423 /* patch vftbl index */
425 *((s4 *) (ra + 4)) |= (s4) ((OFFSET(vftbl_t, table[0]) +
426 sizeof(methodptr) * m->vftblindex) & 0x0000ffff);
428 md_icacheflush(NULL, 0);
434 /* patcher_invokeinterface *****************************************************
438 <patched call position>
439 a7900000 ldq at,0(a0)
440 a79cffa0 ldq at,-96(at)
441 a77c0018 ldq pv,24(at)
444 *******************************************************************************/
446 bool patcher_invokeinterface(patchref_t *pr)
449 unresolved_method *um;
452 /* get stuff from the stack */
455 um = (unresolved_method *) pr->ref;
457 /* get the fieldinfo */
459 if (!(m = resolve_method_eager(um)))
462 PATCH_BACK_ORIGINAL_MCODE;
464 /* if we show disassembly, we have to skip the nop */
469 /* patch interfacetable index */
471 *((s4 *) (ra + 4)) |= (s4) ((OFFSET(vftbl_t, interfacetable[0]) -
472 sizeof(methodptr*) * m->class->index) & 0x0000ffff);
474 /* patch method offset */
476 *((s4 *) (ra + 4 + 4)) |=
477 (s4) ((sizeof(methodptr) * (m - m->class->methods)) & 0x0000ffff);
479 md_icacheflush(NULL, 0);
485 /* patcher_checkcast_interface *************************************************
489 <patched call position>
490 a78e0000 ldq at,0(s5)
491 a3bc001c ldl gp,28(at)
492 23bdfffd lda gp,-3(gp)
493 efa0002e ble gp,0x00000200002bf6b0
494 a7bcffe8 ldq gp,-24(at)
496 *******************************************************************************/
498 bool patcher_checkcast_interface(patchref_t *pr)
501 constant_classref *cr;
504 /* get stuff from the stack */
507 cr = (constant_classref *) pr->ref;
509 /* get the fieldinfo */
511 if (!(c = resolve_classref_eager(cr)))
514 PATCH_BACK_ORIGINAL_MCODE;
516 /* if we show disassembly, we have to skip the nop */
521 /* patch super class index */
523 *((s4 *) (ra + 2 * 4)) |= (s4) (-(c->index) & 0x0000ffff);
525 *((s4 *) (ra + 5 * 4)) |= (s4) ((OFFSET(vftbl_t, interfacetable[0]) -
526 c->index * sizeof(methodptr*)) & 0x0000ffff);
528 md_icacheflush(NULL, 0);
534 /* patcher_instanceof_interface ************************************************
538 <patched call position>
539 a78e0000 ldq at,0(s5)
540 a3bc001c ldl gp,28(at)
541 23bdfffd lda gp,-3(gp)
542 efa0002e ble gp,0x00000200002bf6b0
543 a7bcffe8 ldq gp,-24(at)
545 *******************************************************************************/
547 bool patcher_instanceof_interface(patchref_t *pr)
550 constant_classref *cr;
553 /* get stuff from the stack */
556 cr = (constant_classref *) pr->ref;
558 /* get the fieldinfo */
560 if (!(c = resolve_classref_eager(cr)))
563 PATCH_BACK_ORIGINAL_MCODE;
565 /* if we show disassembly, we have to skip the nop */
570 /* patch super class index */
572 *((s4 *) (ra + 2 * 4)) |= (s4) (-(c->index) & 0x0000ffff);
574 *((s4 *) (ra + 4 * 4)) |= (s4) ((OFFSET(vftbl_t, interfacetable[0]) -
575 c->index * sizeof(methodptr*)) & 0x0000ffff);
577 md_icacheflush(NULL, 0);
584 * These are local overrides for various environment variables in Emacs.
585 * Please do not remove this and leave it at the end of the file, where
586 * Emacs will automagically detect them.
587 * ---------------------------------------------------------------------
590 * indent-tabs-mode: t
594 * vim:noexpandtab:sw=4:ts=4: