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
34 #include "mm/memory.h"
36 #include "native/native.h"
38 #include "vm/builtin.h"
39 #include "vm/exceptions.h"
40 #include "vm/initialize.h"
42 #include "vm/jit/asmpart.h"
43 #include "vm/jit/patcher-common.h"
44 #include "vm/jit/md.h"
45 #include "vm/jit/methodheader.h"
46 #include "vm/jit/stacktrace.h"
48 #include "vmcore/class.h"
49 #include "vmcore/field.h"
50 #include "vmcore/options.h"
51 #include "vmcore/references.h"
52 #include "vm/resolve.h"
55 #define PATCH_BACK_ORIGINAL_MCODE \
56 *((u4 *) pr->mpc) = (u4) pr->mcode; \
57 md_icacheflush(NULL, 0);
60 /* patcher_initialize_class ****************************************************
62 Initalizes a given classinfo pointer. This function does not patch
65 *******************************************************************************/
67 bool patcher_initialize_class(patchref_t *pr)
71 /* get stuff from the stack */
73 c = (classinfo *) pr->ref;
75 /* check if the class is initialized */
77 if (!(c->state & CLASS_INITIALIZED))
78 if (!initialize_class(c))
81 PATCH_BACK_ORIGINAL_MCODE;
86 /* patcher_resolve_class *****************************************************
88 Initalizes a given classinfo pointer. This function does not patch
91 *******************************************************************************/
93 #ifdef ENABLE_VERIFIER
94 bool patcher_resolve_class(patchref_t *pr)
98 /* get stuff from the stack */
100 uc = (unresolved_class *) pr->ref;
102 /* resolve the class and check subtype constraints */
104 if (!resolve_class_eager_no_access_check(uc))
107 PATCH_BACK_ORIGINAL_MCODE;
111 #endif /* ENABLE_VERIFIER */
114 /* patcher_resolve_classref_to_classinfo ***************************************
118 <patched call postition>
119 a61bff80 ldq a0,-128(pv)
123 <patched call position>
124 a63bff80 ldq a1,-128(pv)
126 a77bff78 ldq pv,-136(pv)
131 <patched call position>
132 a63bfe60 ldq a1,-416(pv)
133 a77bfe58 ldq pv,-424(pv)
136 *******************************************************************************/
138 bool patcher_resolve_classref_to_classinfo(patchref_t *pr)
140 constant_classref *cr;
144 /* get stuff from the stack */
146 cr = (constant_classref *) pr->ref;
147 datap = (u1 *) pr->datap;
149 /* get the classinfo */
151 if (!(c = resolve_classref_eager(cr)))
154 PATCH_BACK_ORIGINAL_MCODE;
156 /* patch the classinfo pointer */
158 *((ptrint *) datap) = (ptrint) c;
164 /* patcher_resolve_classref_to_vftbl *******************************************
169 <patched call position>
170 a7940000 ldq at,0(a4)
171 a7bbff28 ldq gp,-216(pv)
173 *******************************************************************************/
175 bool patcher_resolve_classref_to_vftbl(patchref_t *pr)
177 constant_classref *cr;
181 /* get stuff from the stack */
183 cr = (constant_classref *) pr->ref;
184 datap = (u1 *) pr->datap;
186 /* get the fieldinfo */
188 if (!(c = resolve_classref_eager(cr)))
191 PATCH_BACK_ORIGINAL_MCODE;
193 /* patch super class' vftbl */
195 *((ptrint *) datap) = (ptrint) c->vftbl;
201 /* patcher_resolve_classref_to_flags *******************************************
203 CHECKCAST/INSTANCEOF:
205 <patched call position>
207 *******************************************************************************/
209 bool patcher_resolve_classref_to_flags(patchref_t *pr)
211 constant_classref *cr;
215 /* get stuff from the stack */
217 cr = (constant_classref *) pr->ref;
218 datap = (u1 *) pr->datap;
220 /* get the fieldinfo */
222 if (!(c = resolve_classref_eager(cr)))
225 PATCH_BACK_ORIGINAL_MCODE;
227 /* patch class flags */
229 *((s4 *) datap) = (s4) c->flags;
235 /* patcher_resolve_native_function *********************************************
239 *******************************************************************************/
241 #if !defined(WITH_STATIC_CLASSPATH)
242 bool patcher_resolve_native_function(patchref_t *pr)
248 /* get stuff from the stack */
250 m = (methodinfo *) pr->ref;
251 datap = (u1 *) pr->datap;
253 /* resolve native function */
255 if (!(f = native_resolve_function(m)))
258 PATCH_BACK_ORIGINAL_MCODE;
260 /* patch native function pointer */
262 *((ptrint *) datap) = (ptrint) f;
266 #endif /* !defined(WITH_STATIC_CLASSPATH) */
269 /* patcher_get_putstatic *******************************************************
273 <patched call position>
274 a73bff98 ldq t11,-104(pv)
275 a2590000 ldl a2,0(t11)
277 *******************************************************************************/
279 bool patcher_get_putstatic(patchref_t *pr)
281 unresolved_field *uf;
285 /* get stuff from the stack */
287 uf = (unresolved_field *) pr->ref;
288 datap = (u1 *) pr->datap;
290 /* get the fieldinfo */
292 if (!(fi = resolve_field_eager(uf)))
295 /* check if the field's class is initialized */
297 if (!(fi->class->state & CLASS_INITIALIZED))
298 if (!initialize_class(fi->class))
301 PATCH_BACK_ORIGINAL_MCODE;
303 /* patch the field value's address */
305 *((intptr_t *) datap) = (intptr_t) fi->value;
311 /* patcher_get_putfield ********************************************************
315 <patched call position>
316 a2af0020 ldl a5,32(s6)
318 *******************************************************************************/
320 bool patcher_get_putfield(patchref_t *pr)
323 unresolved_field *uf;
327 uf = (unresolved_field *) pr->ref;
329 /* get the fieldinfo */
331 if (!(fi = resolve_field_eager(uf)))
334 PATCH_BACK_ORIGINAL_MCODE;
336 /* if we show disassembly, we have to skip the nop */
341 /* patch the field's offset into the instruction */
343 *((u4 *) ra) |= (s2) (fi->offset & 0x0000ffff);
345 md_icacheflush(NULL, 0);
351 /* patcher_invokestatic_special ************************************************
355 <patched call position>
356 a77bffa8 ldq pv,-88(pv)
359 ******************************************************************************/
361 bool patcher_invokestatic_special(patchref_t *pr)
363 unresolved_method *um;
367 /* get stuff from the stack */
369 um = (unresolved_method *) pr->ref;
370 datap = (u1 *) pr->datap;
372 /* get the fieldinfo */
374 if (!(m = resolve_method_eager(um)))
377 PATCH_BACK_ORIGINAL_MCODE;
379 /* patch stubroutine */
381 *((ptrint *) datap) = (ptrint) m->stubroutine;
387 /* patcher_invokevirtual *******************************************************
391 <patched call position>
392 a7900000 ldq at,0(a0)
393 a77c0100 ldq pv,256(at)
396 *******************************************************************************/
398 bool patcher_invokevirtual(patchref_t *pr)
401 unresolved_method *um;
404 /* get stuff from the stack */
407 um = (unresolved_method *) pr->ref;
409 /* get the fieldinfo */
411 if (!(m = resolve_method_eager(um)))
414 PATCH_BACK_ORIGINAL_MCODE;
416 /* if we show disassembly, we have to skip the nop */
421 /* patch vftbl index */
423 *((s4 *) (ra + 4)) |= (s4) ((OFFSET(vftbl_t, table[0]) +
424 sizeof(methodptr) * m->vftblindex) & 0x0000ffff);
426 md_icacheflush(NULL, 0);
432 /* patcher_invokeinterface *****************************************************
436 <patched call position>
437 a7900000 ldq at,0(a0)
438 a79cffa0 ldq at,-96(at)
439 a77c0018 ldq pv,24(at)
442 *******************************************************************************/
444 bool patcher_invokeinterface(patchref_t *pr)
447 unresolved_method *um;
450 /* get stuff from the stack */
453 um = (unresolved_method *) pr->ref;
455 /* get the fieldinfo */
457 if (!(m = resolve_method_eager(um)))
460 PATCH_BACK_ORIGINAL_MCODE;
462 /* if we show disassembly, we have to skip the nop */
467 /* patch interfacetable index */
469 *((s4 *) (ra + 4)) |= (s4) ((OFFSET(vftbl_t, interfacetable[0]) -
470 sizeof(methodptr*) * m->class->index) & 0x0000ffff);
472 /* patch method offset */
474 *((s4 *) (ra + 4 + 4)) |=
475 (s4) ((sizeof(methodptr) * (m - m->class->methods)) & 0x0000ffff);
477 md_icacheflush(NULL, 0);
483 /* patcher_checkcast_interface *************************************************
487 <patched call position>
488 a78e0000 ldq at,0(s5)
489 a3bc001c ldl gp,28(at)
490 23bdfffd lda gp,-3(gp)
491 efa0002e ble gp,0x00000200002bf6b0
492 a7bcffe8 ldq gp,-24(at)
494 *******************************************************************************/
496 bool patcher_checkcast_interface(patchref_t *pr)
499 constant_classref *cr;
502 /* get stuff from the stack */
505 cr = (constant_classref *) pr->ref;
507 /* get the fieldinfo */
509 if (!(c = resolve_classref_eager(cr)))
512 PATCH_BACK_ORIGINAL_MCODE;
514 /* if we show disassembly, we have to skip the nop */
519 /* patch super class index */
521 *((s4 *) (ra + 2 * 4)) |= (s4) (-(c->index) & 0x0000ffff);
523 *((s4 *) (ra + 5 * 4)) |= (s4) ((OFFSET(vftbl_t, interfacetable[0]) -
524 c->index * sizeof(methodptr*)) & 0x0000ffff);
526 md_icacheflush(NULL, 0);
532 /* patcher_instanceof_interface ************************************************
536 <patched call position>
537 a78e0000 ldq at,0(s5)
538 a3bc001c ldl gp,28(at)
539 23bdfffd lda gp,-3(gp)
540 efa0002e ble gp,0x00000200002bf6b0
541 a7bcffe8 ldq gp,-24(at)
543 *******************************************************************************/
545 bool patcher_instanceof_interface(patchref_t *pr)
548 constant_classref *cr;
551 /* get stuff from the stack */
554 cr = (constant_classref *) pr->ref;
556 /* get the fieldinfo */
558 if (!(c = resolve_classref_eager(cr)))
561 PATCH_BACK_ORIGINAL_MCODE;
563 /* if we show disassembly, we have to skip the nop */
568 /* patch super class index */
570 *((s4 *) (ra + 2 * 4)) |= (s4) (-(c->index) & 0x0000ffff);
572 *((s4 *) (ra + 4 * 4)) |= (s4) ((OFFSET(vftbl_t, interfacetable[0]) -
573 c->index * sizeof(methodptr*)) & 0x0000ffff);
575 md_icacheflush(NULL, 0);
582 * These are local overrides for various environment variables in Emacs.
583 * Please do not remove this and leave it at the end of the file, where
584 * Emacs will automagically detect them.
585 * ---------------------------------------------------------------------
588 * indent-tabs-mode: t
592 * vim:noexpandtab:sw=4:ts=4: