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_patch_code **********************************************************
62 Just patches back the original machine code.
64 *******************************************************************************/
66 void patcher_patch_code(patchref_t *pr)
68 PATCH_BACK_ORIGINAL_MCODE;
72 /* patcher_resolve_classref_to_classinfo ***************************************
76 <patched call postition>
77 a61bff80 ldq a0,-128(pv)
81 <patched call position>
82 a63bff80 ldq a1,-128(pv)
84 a77bff78 ldq pv,-136(pv)
89 <patched call position>
90 a63bfe60 ldq a1,-416(pv)
91 a77bfe58 ldq pv,-424(pv)
94 *******************************************************************************/
96 bool patcher_resolve_classref_to_classinfo(patchref_t *pr)
98 constant_classref *cr;
102 /* get stuff from the stack */
104 cr = (constant_classref *) pr->ref;
105 datap = (u1 *) pr->datap;
107 /* get the classinfo */
109 if (!(c = resolve_classref_eager(cr)))
112 PATCH_BACK_ORIGINAL_MCODE;
114 /* patch the classinfo pointer */
116 *((ptrint *) datap) = (ptrint) c;
122 /* patcher_resolve_classref_to_vftbl *******************************************
127 <patched call position>
128 a7940000 ldq at,0(a4)
129 a7bbff28 ldq gp,-216(pv)
131 *******************************************************************************/
133 bool patcher_resolve_classref_to_vftbl(patchref_t *pr)
135 constant_classref *cr;
139 /* get stuff from the stack */
141 cr = (constant_classref *) pr->ref;
142 datap = (u1 *) pr->datap;
144 /* get the fieldinfo */
146 if (!(c = resolve_classref_eager(cr)))
149 PATCH_BACK_ORIGINAL_MCODE;
151 /* patch super class' vftbl */
153 *((ptrint *) datap) = (ptrint) c->vftbl;
159 /* patcher_resolve_classref_to_flags *******************************************
161 CHECKCAST/INSTANCEOF:
163 <patched call position>
165 *******************************************************************************/
167 bool patcher_resolve_classref_to_flags(patchref_t *pr)
169 constant_classref *cr;
173 /* get stuff from the stack */
175 cr = (constant_classref *) pr->ref;
176 datap = (u1 *) pr->datap;
178 /* get the fieldinfo */
180 if (!(c = resolve_classref_eager(cr)))
183 PATCH_BACK_ORIGINAL_MCODE;
185 /* patch class flags */
187 *((s4 *) datap) = (s4) c->flags;
193 /* patcher_get_putstatic *******************************************************
197 <patched call position>
198 a73bff98 ldq t11,-104(pv)
199 a2590000 ldl a2,0(t11)
201 *******************************************************************************/
203 bool patcher_get_putstatic(patchref_t *pr)
205 unresolved_field *uf;
209 /* get stuff from the stack */
211 uf = (unresolved_field *) pr->ref;
212 datap = (u1 *) pr->datap;
214 /* get the fieldinfo */
216 if (!(fi = resolve_field_eager(uf)))
219 /* check if the field's class is initialized */
221 if (!(fi->class->state & CLASS_INITIALIZED))
222 if (!initialize_class(fi->class))
225 PATCH_BACK_ORIGINAL_MCODE;
227 /* patch the field value's address */
229 *((intptr_t *) datap) = (intptr_t) fi->value;
235 /* patcher_get_putfield ********************************************************
239 <patched call position>
240 a2af0020 ldl a5,32(s6)
242 *******************************************************************************/
244 bool patcher_get_putfield(patchref_t *pr)
247 unresolved_field *uf;
251 uf = (unresolved_field *) pr->ref;
253 /* get the fieldinfo */
255 if (!(fi = resolve_field_eager(uf)))
258 PATCH_BACK_ORIGINAL_MCODE;
260 /* if we show disassembly, we have to skip the nop */
265 /* patch the field's offset into the instruction */
267 *((u4 *) ra) |= (s2) (fi->offset & 0x0000ffff);
269 md_icacheflush(NULL, 0);
275 /* patcher_invokestatic_special ************************************************
279 <patched call position>
280 a77bffa8 ldq pv,-88(pv)
283 ******************************************************************************/
285 bool patcher_invokestatic_special(patchref_t *pr)
287 unresolved_method *um;
291 /* get stuff from the stack */
293 um = (unresolved_method *) pr->ref;
294 datap = (u1 *) pr->datap;
296 /* get the fieldinfo */
298 if (!(m = resolve_method_eager(um)))
301 PATCH_BACK_ORIGINAL_MCODE;
303 /* patch stubroutine */
305 *((ptrint *) datap) = (ptrint) m->stubroutine;
311 /* patcher_invokevirtual *******************************************************
315 <patched call position>
316 a7900000 ldq at,0(a0)
317 a77c0100 ldq pv,256(at)
320 *******************************************************************************/
322 bool patcher_invokevirtual(patchref_t *pr)
325 unresolved_method *um;
328 /* get stuff from the stack */
331 um = (unresolved_method *) pr->ref;
333 /* get the fieldinfo */
335 if (!(m = resolve_method_eager(um)))
338 PATCH_BACK_ORIGINAL_MCODE;
340 /* if we show disassembly, we have to skip the nop */
345 /* patch vftbl index */
347 *((s4 *) (ra + 4)) |= (s4) ((OFFSET(vftbl_t, table[0]) +
348 sizeof(methodptr) * m->vftblindex) & 0x0000ffff);
350 md_icacheflush(NULL, 0);
356 /* patcher_invokeinterface *****************************************************
360 <patched call position>
361 a7900000 ldq at,0(a0)
362 a79cffa0 ldq at,-96(at)
363 a77c0018 ldq pv,24(at)
366 *******************************************************************************/
368 bool patcher_invokeinterface(patchref_t *pr)
371 unresolved_method *um;
374 /* get stuff from the stack */
377 um = (unresolved_method *) pr->ref;
379 /* get the fieldinfo */
381 if (!(m = resolve_method_eager(um)))
384 PATCH_BACK_ORIGINAL_MCODE;
386 /* if we show disassembly, we have to skip the nop */
391 /* patch interfacetable index */
393 *((s4 *) (ra + 4)) |= (s4) ((OFFSET(vftbl_t, interfacetable[0]) -
394 sizeof(methodptr*) * m->class->index) & 0x0000ffff);
396 /* patch method offset */
398 *((s4 *) (ra + 4 + 4)) |=
399 (s4) ((sizeof(methodptr) * (m - m->class->methods)) & 0x0000ffff);
401 md_icacheflush(NULL, 0);
407 /* patcher_checkcast_interface *************************************************
411 <patched call position>
412 a78e0000 ldq at,0(s5)
413 a3bc001c ldl gp,28(at)
414 23bdfffd lda gp,-3(gp)
415 efa0002e ble gp,0x00000200002bf6b0
416 a7bcffe8 ldq gp,-24(at)
418 *******************************************************************************/
420 bool patcher_checkcast_interface(patchref_t *pr)
423 constant_classref *cr;
426 /* get stuff from the stack */
429 cr = (constant_classref *) pr->ref;
431 /* get the fieldinfo */
433 if (!(c = resolve_classref_eager(cr)))
436 PATCH_BACK_ORIGINAL_MCODE;
438 /* if we show disassembly, we have to skip the nop */
443 /* patch super class index */
445 *((s4 *) (ra + 2 * 4)) |= (s4) (-(c->index) & 0x0000ffff);
447 *((s4 *) (ra + 5 * 4)) |= (s4) ((OFFSET(vftbl_t, interfacetable[0]) -
448 c->index * sizeof(methodptr*)) & 0x0000ffff);
450 md_icacheflush(NULL, 0);
456 /* patcher_instanceof_interface ************************************************
460 <patched call position>
461 a78e0000 ldq at,0(s5)
462 a3bc001c ldl gp,28(at)
463 23bdfffd lda gp,-3(gp)
464 efa0002e ble gp,0x00000200002bf6b0
465 a7bcffe8 ldq gp,-24(at)
467 *******************************************************************************/
469 bool patcher_instanceof_interface(patchref_t *pr)
472 constant_classref *cr;
475 /* get stuff from the stack */
478 cr = (constant_classref *) pr->ref;
480 /* get the fieldinfo */
482 if (!(c = resolve_classref_eager(cr)))
485 PATCH_BACK_ORIGINAL_MCODE;
487 /* if we show disassembly, we have to skip the nop */
492 /* patch super class index */
494 *((s4 *) (ra + 2 * 4)) |= (s4) (-(c->index) & 0x0000ffff);
496 *((s4 *) (ra + 4 * 4)) |= (s4) ((OFFSET(vftbl_t, interfacetable[0]) -
497 c->index * sizeof(methodptr*)) & 0x0000ffff);
499 md_icacheflush(NULL, 0);
506 * These are local overrides for various environment variables in Emacs.
507 * Please do not remove this and leave it at the end of the file, where
508 * Emacs will automagically detect them.
509 * ---------------------------------------------------------------------
512 * indent-tabs-mode: t
516 * vim:noexpandtab:sw=4:ts=4: