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 "vm/jit/alpha/md.h"
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/methodheader.h"
47 #include "vm/jit/stacktrace.h"
49 #include "vmcore/class.h"
50 #include "vmcore/field.h"
51 #include "vmcore/options.h"
52 #include "vmcore/references.h"
53 #include "vm/resolve.h"
56 #define PATCH_BACK_ORIGINAL_MCODE \
57 *((u4 *) pr->mpc) = (u4) pr->mcode; \
58 md_icacheflush(NULL, 0);
61 /* patcher_patch_code **********************************************************
63 Just patches back the original machine code.
65 *******************************************************************************/
67 void patcher_patch_code(patchref_t *pr)
69 PATCH_BACK_ORIGINAL_MCODE;
73 /* patcher_resolve_classref_to_classinfo ***************************************
77 <patched call postition>
78 a61bff80 ldq a0,-128(pv)
82 <patched call position>
83 a63bff80 ldq a1,-128(pv)
85 a77bff78 ldq pv,-136(pv)
90 <patched call position>
91 a63bfe60 ldq a1,-416(pv)
92 a77bfe58 ldq pv,-424(pv)
95 *******************************************************************************/
97 bool patcher_resolve_classref_to_classinfo(patchref_t *pr)
99 constant_classref *cr;
103 /* get stuff from the stack */
105 cr = (constant_classref *) pr->ref;
106 datap = (u1 *) pr->datap;
108 /* get the classinfo */
110 if (!(c = resolve_classref_eager(cr)))
113 PATCH_BACK_ORIGINAL_MCODE;
115 /* patch the classinfo pointer */
117 *((ptrint *) datap) = (ptrint) c;
123 /* patcher_resolve_classref_to_vftbl *******************************************
128 <patched call position>
129 a7940000 ldq at,0(a4)
130 a7bbff28 ldq gp,-216(pv)
132 *******************************************************************************/
134 bool patcher_resolve_classref_to_vftbl(patchref_t *pr)
136 constant_classref *cr;
140 /* get stuff from the stack */
142 cr = (constant_classref *) pr->ref;
143 datap = (u1 *) pr->datap;
145 /* get the fieldinfo */
147 if (!(c = resolve_classref_eager(cr)))
150 PATCH_BACK_ORIGINAL_MCODE;
152 /* patch super class' vftbl */
154 *((ptrint *) datap) = (ptrint) c->vftbl;
160 /* patcher_resolve_classref_to_flags *******************************************
162 CHECKCAST/INSTANCEOF:
164 <patched call position>
166 *******************************************************************************/
168 bool patcher_resolve_classref_to_flags(patchref_t *pr)
170 constant_classref *cr;
174 /* get stuff from the stack */
176 cr = (constant_classref *) pr->ref;
177 datap = (u1 *) pr->datap;
179 /* get the fieldinfo */
181 if (!(c = resolve_classref_eager(cr)))
184 PATCH_BACK_ORIGINAL_MCODE;
186 /* patch class flags */
188 *((s4 *) datap) = (s4) c->flags;
194 /* patcher_get_putstatic *******************************************************
198 <patched call position>
199 a73bff98 ldq t11,-104(pv)
200 a2590000 ldl a2,0(t11)
202 *******************************************************************************/
204 bool patcher_get_putstatic(patchref_t *pr)
206 unresolved_field *uf;
210 /* get stuff from the stack */
212 uf = (unresolved_field *) pr->ref;
213 datap = (u1 *) pr->datap;
215 /* get the fieldinfo */
217 if (!(fi = resolve_field_eager(uf)))
220 /* check if the field's class is initialized */
222 if (!(fi->class->state & CLASS_INITIALIZED))
223 if (!initialize_class(fi->class))
226 PATCH_BACK_ORIGINAL_MCODE;
228 /* patch the field value's address */
230 *((intptr_t *) datap) = (intptr_t) fi->value;
236 /* patcher_get_putfield ********************************************************
240 <patched call position>
241 a2af0020 ldl a5,32(s6)
243 *******************************************************************************/
245 bool patcher_get_putfield(patchref_t *pr)
248 unresolved_field *uf;
252 uf = (unresolved_field *) pr->ref;
254 /* get the fieldinfo */
256 if (!(fi = resolve_field_eager(uf)))
259 PATCH_BACK_ORIGINAL_MCODE;
261 /* if we show disassembly, we have to skip the nop */
266 /* patch the field's offset into the instruction */
268 *((u4 *) ra) |= (s2) (fi->offset & 0x0000ffff);
270 md_icacheflush(NULL, 0);
276 /* patcher_invokestatic_special ************************************************
280 <patched call position>
281 a77bffa8 ldq pv,-88(pv)
284 ******************************************************************************/
286 bool patcher_invokestatic_special(patchref_t *pr)
288 unresolved_method *um;
292 /* get stuff from the stack */
294 um = (unresolved_method *) pr->ref;
295 datap = (u1 *) pr->datap;
297 /* get the fieldinfo */
299 if (!(m = resolve_method_eager(um)))
302 PATCH_BACK_ORIGINAL_MCODE;
304 /* patch stubroutine */
306 *((ptrint *) datap) = (ptrint) m->stubroutine;
312 /* patcher_invokevirtual *******************************************************
316 <patched call position>
317 a7900000 ldq at,0(a0)
318 a77c0100 ldq pv,256(at)
321 *******************************************************************************/
323 bool patcher_invokevirtual(patchref_t *pr)
326 unresolved_method *um;
329 /* get stuff from the stack */
332 um = (unresolved_method *) pr->ref;
334 /* get the fieldinfo */
336 if (!(m = resolve_method_eager(um)))
339 PATCH_BACK_ORIGINAL_MCODE;
341 /* if we show disassembly, we have to skip the nop */
346 /* patch vftbl index */
348 *((s4 *) (ra + 4)) |= (s4) ((OFFSET(vftbl_t, table[0]) +
349 sizeof(methodptr) * m->vftblindex) & 0x0000ffff);
351 md_icacheflush(NULL, 0);
357 /* patcher_invokeinterface *****************************************************
361 <patched call position>
362 a7900000 ldq at,0(a0)
363 a79cffa0 ldq at,-96(at)
364 a77c0018 ldq pv,24(at)
367 *******************************************************************************/
369 bool patcher_invokeinterface(patchref_t *pr)
372 unresolved_method *um;
375 /* get stuff from the stack */
378 um = (unresolved_method *) pr->ref;
380 /* get the fieldinfo */
382 if (!(m = resolve_method_eager(um)))
385 PATCH_BACK_ORIGINAL_MCODE;
387 /* if we show disassembly, we have to skip the nop */
392 /* patch interfacetable index */
394 *((s4 *) (ra + 4)) |= (s4) ((OFFSET(vftbl_t, interfacetable[0]) -
395 sizeof(methodptr*) * m->class->index) & 0x0000ffff);
397 /* patch method offset */
399 *((s4 *) (ra + 4 + 4)) |=
400 (s4) ((sizeof(methodptr) * (m - m->class->methods)) & 0x0000ffff);
402 md_icacheflush(NULL, 0);
408 /* patcher_checkcast_interface *************************************************
412 <patched call position>
413 a78e0000 ldq at,0(s5)
414 a3bc001c ldl gp,28(at)
415 23bdfffd lda gp,-3(gp)
416 efa0002e ble gp,0x00000200002bf6b0
417 a7bcffe8 ldq gp,-24(at)
419 *******************************************************************************/
421 bool patcher_checkcast_interface(patchref_t *pr)
424 constant_classref *cr;
427 /* get stuff from the stack */
430 cr = (constant_classref *) pr->ref;
432 /* get the fieldinfo */
434 if (!(c = resolve_classref_eager(cr)))
437 PATCH_BACK_ORIGINAL_MCODE;
439 /* if we show disassembly, we have to skip the nop */
444 /* patch super class index */
446 *((s4 *) (ra + 2 * 4)) |= (s4) (-(c->index) & 0x0000ffff);
448 *((s4 *) (ra + 5 * 4)) |= (s4) ((OFFSET(vftbl_t, interfacetable[0]) -
449 c->index * sizeof(methodptr*)) & 0x0000ffff);
451 md_icacheflush(NULL, 0);
457 /* patcher_instanceof_interface ************************************************
461 <patched call position>
462 a78e0000 ldq at,0(s5)
463 a3bc001c ldl gp,28(at)
464 23bdfffd lda gp,-3(gp)
465 efa0002e ble gp,0x00000200002bf6b0
466 a7bcffe8 ldq gp,-24(at)
468 *******************************************************************************/
470 bool patcher_instanceof_interface(patchref_t *pr)
473 constant_classref *cr;
476 /* get stuff from the stack */
479 cr = (constant_classref *) pr->ref;
481 /* get the fieldinfo */
483 if (!(c = resolve_classref_eager(cr)))
486 PATCH_BACK_ORIGINAL_MCODE;
488 /* if we show disassembly, we have to skip the nop */
493 /* patch super class index */
495 *((s4 *) (ra + 2 * 4)) |= (s4) (-(c->index) & 0x0000ffff);
497 *((s4 *) (ra + 4 * 4)) |= (s4) ((OFFSET(vftbl_t, interfacetable[0]) -
498 c->index * sizeof(methodptr*)) & 0x0000ffff);
500 md_icacheflush(NULL, 0);
507 * These are local overrides for various environment variables in Emacs.
508 * Please do not remove this and leave it at the end of the file, where
509 * Emacs will automagically detect them.
510 * ---------------------------------------------------------------------
513 * indent-tabs-mode: t
517 * vim:noexpandtab:sw=4:ts=4: