1 /* src/vm/jit/alpha/patcher.c - Alpha code patching functions
3 Copyright (C) 1996-2005 R. Grafl, A. Krall, C. Kruegel, C. Oates,
4 R. Obermaisser, M. Platter, M. Probst, S. Ring, E. Steiner,
5 C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich, J. Wenninger,
6 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., 59 Temple Place - Suite 330, Boston, MA
25 Contact: cacao@complang.tuwien.ac.at
27 Authors: Christian Thalinger
31 $Id: patcher.c 3868 2005-12-03 15:25:18Z twisti $
39 #include "mm/memory.h"
40 #include "native/native.h"
41 #include "vm/builtin.h"
43 #include "vm/initialize.h"
44 #include "vm/options.h"
45 #include "vm/references.h"
46 #include "vm/resolve.h"
47 #include "vm/jit/asmpart.h"
48 #include "vm/jit/patcher.h"
51 /* patcher_get_putstatic *******************************************************
55 <patched call position>
56 a73bff98 ldq t11,-104(pv)
57 a2590000 ldl a2,0(t11)
59 *******************************************************************************/
61 bool patcher_get_putstatic(u1 *sp)
71 /* get stuff from the stack */
73 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
74 o = (java_objectheader *) *((ptrint *) (sp + 4 * 8));
75 mcode = *((u4 *) (sp + 3 * 8));
76 uf = (unresolved_field *) *((ptrint *) (sp + 2 * 8));
77 disp = *((s4 *) (sp + 1 * 8));
78 pv = (u1 *) *((ptrint *) (sp + 0 * 8));
80 /* calculate and set the new return address */
83 *((ptrint *) (sp + 5 * 8)) = (ptrint) ra;
87 /* get the fieldinfo */
89 if (!(fi = resolve_field_eager(uf))) {
95 /* check if the field's class is initialized */
97 if (!(fi->class->state & CLASS_INITIALIZED)) {
98 if (!initialize_class(fi->class)) {
105 /* patch back original code */
107 *((u4 *) ra) = mcode;
109 /* synchronize instruction cache */
111 asm_sync_instruction_cache();
113 /* patch the field value's address */
115 *((ptrint *) (pv + disp)) = (ptrint) &(fi->value);
117 PATCHER_MARK_PATCHED_MONITOREXIT;
123 /* patcher_get_putfield ********************************************************
127 <patched call position>
128 a2af0020 ldl a5,32(s6)
130 *******************************************************************************/
132 bool patcher_get_putfield(u1 *sp)
135 java_objectheader *o;
137 unresolved_field *uf;
140 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
141 o = (java_objectheader *) *((ptrint *) (sp + 4 * 8));
142 mcode = *((u4 *) (sp + 3 * 8));
143 uf = (unresolved_field *) *((ptrint *) (sp + 2 * 8));
145 /* calculate and set the new return address */
148 *((ptrint *) (sp + 5 * 8)) = (ptrint) ra;
150 PATCHER_MONITORENTER;
152 /* get the fieldinfo */
154 if (!(fi = resolve_field_eager(uf))) {
160 /* patch back original code */
162 *((u4 *) ra) = mcode;
164 /* if we show disassembly, we have to skip the nop */
166 if (opt_showdisassemble)
169 /* patch the field's offset */
171 *((u4 *) ra) |= (s2) (fi->offset & 0x0000ffff);
173 /* synchronize instruction cache */
175 asm_sync_instruction_cache();
177 PATCHER_MARK_PATCHED_MONITOREXIT;
183 /* patcher_aconst **************************************************************
187 <patched call postition>
188 a61bff80 ldq a0,-128(pv)
190 *******************************************************************************/
192 bool patcher_aconst(u1 *sp)
195 java_objectheader *o;
197 constant_classref *cr;
202 /* get stuff from the stack */
204 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
205 o = (java_objectheader *) *((ptrint *) (sp + 4 * 8));
206 mcode = *((u4 *) (sp + 3 * 8));
207 cr = (constant_classref *) *((ptrint *) (sp + 2 * 8));
208 disp = *((s4 *) (sp + 1 * 8));
209 pv = (u1 *) *((ptrint *) (sp + 0 * 8));
211 /* calculate and set the new return address */
214 *((ptrint *) (sp + 5 * 8)) = (ptrint) ra;
216 PATCHER_MONITORENTER;
218 /* get the classinfo */
220 if (!(c = resolve_classref_eager(cr))) {
226 /* patch back original code */
228 *((u4 *) ra) = mcode;
230 /* synchronize instruction cache */
232 asm_sync_instruction_cache();
234 /* patch the classinfo pointer */
236 *((ptrint *) (pv + disp)) = (ptrint) c;
238 PATCHER_MARK_PATCHED_MONITOREXIT;
244 /* patcher_builtin_multianewarray **********************************************
248 <patched call position>
249 a63bff80 ldq a1,-128(pv)
251 a77bff78 ldq pv,-136(pv)
254 *******************************************************************************/
256 bool patcher_builtin_multianewarray(u1 *sp)
259 java_objectheader *o;
261 constant_classref *cr;
266 /* get stuff from the stack */
268 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
269 o = (java_objectheader *) *((ptrint *) (sp + 4 * 8));
270 mcode = *((u4 *) (sp + 3 * 8));
271 cr = (constant_classref *) *((ptrint *) (sp + 2 * 8));
272 disp = *((s4 *) (sp + 1 * 8));
273 pv = (u1 *) *((ptrint *) (sp + 0 * 8));
275 /* calculate and set the new return address */
278 *((ptrint *) (sp + 5 * 8)) = (ptrint) ra;
280 PATCHER_MONITORENTER;
282 /* get the classinfo */
284 if (!(c = resolve_classref_eager(cr))) {
290 /* patch back original code */
292 *((u4 *) ra) = mcode;
294 /* synchronize instruction cache */
296 asm_sync_instruction_cache();
298 /* patch the classinfo pointer */
300 *((ptrint *) (pv + disp)) = (ptrint) c;
302 PATCHER_MARK_PATCHED_MONITOREXIT;
308 /* patcher_builtin_arraycheckcast **********************************************
312 <patched call position>
313 a63bfe60 ldq a1,-416(pv)
314 a77bfe58 ldq pv,-424(pv)
317 *******************************************************************************/
319 bool patcher_builtin_arraycheckcast(u1 *sp)
322 java_objectheader *o;
324 constant_classref *cr;
329 /* get stuff from the stack */
331 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
332 o = (java_objectheader *) *((ptrint *) (sp + 4 * 8));
333 mcode = *((u4 *) (sp + 3 * 8));
334 cr = (constant_classref *) *((ptrint *) (sp + 2 * 8));
335 disp = *((s4 *) (sp + 1 * 8));
336 pv = (u1 *) *((ptrint *) (sp + 0 * 8));
338 /* calculate and set the new return address */
341 *((ptrint *) (sp + 5 * 8)) = (ptrint) ra;
343 PATCHER_MONITORENTER;
345 /* get the classinfo */
347 if (!(c = resolve_classref_eager(cr))) {
353 /* patch back original code */
355 *((u4 *) ra) = mcode;
357 /* synchronize instruction cache */
359 asm_sync_instruction_cache();
361 /* patch the classinfo pointer */
363 *((ptrint *) (pv + disp)) = (ptrint) c;
365 PATCHER_MARK_PATCHED_MONITOREXIT;
371 /* patcher_invokestatic_special ************************************************
375 <patched call position>
376 a77bffa8 ldq pv,-88(pv)
379 ******************************************************************************/
381 bool patcher_invokestatic_special(u1 *sp)
384 java_objectheader *o;
386 unresolved_method *um;
391 /* get stuff from the stack */
393 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
394 o = (java_objectheader *) *((ptrint *) (sp + 4 * 8));
395 mcode = *((u4 *) (sp + 3 * 8));
396 um = (unresolved_method *) *((ptrint *) (sp + 2 * 8));
397 disp = *((s4 *) (sp + 1 * 8));
398 pv = (u1 *) *((ptrint *) (sp + 0 * 8));
400 /* calculate and set the new return address */
403 *((ptrint *) (sp + 5 * 8)) = (ptrint) ra;
405 PATCHER_MONITORENTER;
407 /* get the fieldinfo */
409 if (!(m = resolve_method_eager(um))) {
415 /* patch back original code */
417 *((u4 *) ra) = mcode;
419 /* synchronize instruction cache */
421 asm_sync_instruction_cache();
423 /* patch stubroutine */
425 *((ptrint *) (pv + disp)) = (ptrint) m->stubroutine;
427 PATCHER_MARK_PATCHED_MONITOREXIT;
433 /* patcher_invokevirtual *******************************************************
437 <patched call position>
438 a7900000 ldq at,0(a0)
439 a77c0100 ldq pv,256(at)
442 *******************************************************************************/
444 bool patcher_invokevirtual(u1 *sp)
447 java_objectheader *o;
449 unresolved_method *um;
452 /* get stuff from the stack */
454 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
455 o = (java_objectheader *) *((ptrint *) (sp + 4 * 8));
456 mcode = *((u4 *) (sp + 3 * 8));
457 um = (unresolved_method *) *((ptrint *) (sp + 2 * 8));
459 /* calculate and set the new return address */
462 *((ptrint *) (sp + 5 * 8)) = (ptrint) ra;
464 PATCHER_MONITORENTER;
466 /* get the fieldinfo */
468 if (!(m = resolve_method_eager(um))) {
474 /* patch back original code */
476 *((u4 *) ra) = mcode;
478 /* if we show disassembly, we have to skip the nop */
480 if (opt_showdisassemble)
483 /* patch vftbl index */
485 *((s4 *) (ra + 4)) |= (s4) ((OFFSET(vftbl_t, table[0]) +
486 sizeof(methodptr) * m->vftblindex) & 0x0000ffff);
488 /* synchronize instruction cache */
490 asm_sync_instruction_cache();
492 PATCHER_MARK_PATCHED_MONITOREXIT;
498 /* patcher_invokeinterface *****************************************************
502 <patched call position>
503 a7900000 ldq at,0(a0)
504 a79cffa0 ldq at,-96(at)
505 a77c0018 ldq pv,24(at)
508 *******************************************************************************/
510 bool patcher_invokeinterface(u1 *sp)
513 java_objectheader *o;
515 unresolved_method *um;
518 /* get stuff from the stack */
520 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
521 o = (java_objectheader *) *((ptrint *) (sp + 4 * 8));
522 mcode = *((u4 *) (sp + 3 * 8));
523 um = (unresolved_method *) *((ptrint *) (sp + 2 * 8));
525 /* calculate and set the new return address */
528 *((ptrint *) (sp + 5 * 8)) = (ptrint) ra;
530 PATCHER_MONITORENTER;
532 /* get the fieldinfo */
534 if (!(m = resolve_method_eager(um))) {
540 /* patch back original code */
542 *((u4 *) ra) = mcode;
544 /* if we show disassembly, we have to skip the nop */
546 if (opt_showdisassemble)
549 /* patch interfacetable index */
551 *((s4 *) (ra + 4)) |= (s4) ((OFFSET(vftbl_t, interfacetable[0]) -
552 sizeof(methodptr*) * m->class->index) & 0x0000ffff);
554 /* patch method offset */
556 *((s4 *) (ra + 4 + 4)) |=
557 (s4) ((sizeof(methodptr) * (m - m->class->methods)) & 0x0000ffff);
559 /* synchronize instruction cache */
561 asm_sync_instruction_cache();
563 PATCHER_MARK_PATCHED_MONITOREXIT;
569 /* patcher_checkcast_instanceof_flags ******************************************
573 <patched call position>
575 *******************************************************************************/
577 bool patcher_checkcast_instanceof_flags(u1 *sp)
580 java_objectheader *o;
582 constant_classref *cr;
587 /* get stuff from the stack */
589 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
590 o = (java_objectheader *) *((ptrint *) (sp + 4 * 8));
591 mcode = *((u4 *) (sp + 3 * 8));
592 cr = (constant_classref *) *((ptrint *) (sp + 2 * 8));
593 disp = *((s4 *) (sp + 1 * 8));
594 pv = (u1 *) *((ptrint *) (sp + 0 * 8));
596 /* calculate and set the new return address */
599 *((ptrint *) (sp + 5 * 8)) = (ptrint) ra;
601 PATCHER_MONITORENTER;
603 /* get the fieldinfo */
605 if (!(c = resolve_classref_eager(cr))) {
611 /* patch back original code */
613 *((u4 *) ra) = mcode;
615 /* synchronize instruction cache */
617 asm_sync_instruction_cache();
619 /* patch class flags */
621 *((s4 *) (pv + disp)) = (s4) c->flags;
623 PATCHER_MARK_PATCHED_MONITOREXIT;
629 /* patcher_checkcast_instanceof_interface **************************************
633 <patched call position>
634 a78e0000 ldq at,0(s5)
635 a3bc001c ldl gp,28(at)
636 23bdfffd lda gp,-3(gp)
637 efa0002e ble gp,0x00000200002bf6b0
638 a7bcffe8 ldq gp,-24(at)
640 *******************************************************************************/
642 bool patcher_checkcast_instanceof_interface(u1 *sp)
645 java_objectheader *o;
647 constant_classref *cr;
650 /* get stuff from the stack */
652 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
653 o = (java_objectheader *) *((ptrint *) (sp + 4 * 8));
654 mcode = *((u4 *) (sp + 3 * 8));
655 cr = (constant_classref *) *((ptrint *) (sp + 2 * 8));
657 /* calculate and set the new return address */
660 *((ptrint *) (sp + 5 * 8)) = (ptrint) ra;
662 PATCHER_MONITORENTER;
664 /* get the fieldinfo */
666 if (!(c = resolve_classref_eager(cr))) {
672 /* patch back original code */
674 *((u4 *) ra) = mcode;
676 /* if we show disassembly, we have to skip the nop */
678 if (opt_showdisassemble)
681 /* patch super class index */
683 *((s4 *) (ra + 2 * 4)) |= (s4) (-(c->index) & 0x0000ffff);
685 *((s4 *) (ra + 4 * 4)) |= (s4) ((OFFSET(vftbl_t, interfacetable[0]) -
686 c->index * sizeof(methodptr*)) & 0x0000ffff);
688 /* synchronize instruction cache */
690 asm_sync_instruction_cache();
692 PATCHER_MARK_PATCHED_MONITOREXIT;
698 /* patcher_checkcast_instanceof_class ******************************************
702 <patched call position>
703 a7940000 ldq at,0(a4)
704 a7bbff28 ldq gp,-216(pv)
706 *******************************************************************************/
708 bool patcher_checkcast_instanceof_class(u1 *sp)
711 java_objectheader *o;
713 constant_classref *cr;
718 /* get stuff from the stack */
720 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
721 o = (java_objectheader *) *((ptrint *) (sp + 4 * 8));
722 mcode = *((u4 *) (sp + 3 * 8));
723 cr = (constant_classref *) *((ptrint *) (sp + 2 * 8));
724 disp = *((s4 *) (sp + 1 * 8));
725 pv = (u1 *) *((ptrint *) (sp + 0 * 8));
727 /* calculate and set the new return address */
730 *((ptrint *) (sp + 5 * 8)) = (ptrint) ra;
732 PATCHER_MONITORENTER;
734 /* get the fieldinfo */
736 if (!(c = resolve_classref_eager(cr))) {
742 /* patch back original code */
744 *((u4 *) ra) = mcode;
746 /* synchronize instruction cache */
748 asm_sync_instruction_cache();
750 /* patch super class' vftbl */
752 *((ptrint *) (pv + disp)) = (ptrint) c->vftbl;
754 PATCHER_MARK_PATCHED_MONITOREXIT;
760 /* patcher_clinit **************************************************************
764 *******************************************************************************/
766 bool patcher_clinit(u1 *sp)
769 java_objectheader *o;
773 /* get stuff from the stack */
775 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
776 o = (java_objectheader *) *((ptrint *) (sp + 4 * 8));
777 mcode = *((u4 *) (sp + 3 * 8));
778 c = (classinfo *) *((ptrint *) (sp + 2 * 8));
780 /* calculate and set the new return address */
783 *((ptrint *) (sp + 5 * 8)) = (ptrint) ra;
785 PATCHER_MONITORENTER;
787 /* check if the class is initialized */
789 if (!(c->state & CLASS_INITIALIZED)) {
790 if (!initialize_class(c)) {
797 /* patch back original code */
799 *((u4 *) ra) = mcode;
801 /* synchronize instruction cache */
803 asm_sync_instruction_cache();
805 PATCHER_MARK_PATCHED_MONITOREXIT;
811 /* patcher_athrow_areturn ******************************************************
815 <patched call position>
817 *******************************************************************************/
819 #ifdef ENABLE_VERIFIER
820 bool patcher_athrow_areturn(u1 *sp)
823 java_objectheader *o;
825 unresolved_class *uc;
828 /* get stuff from the stack */
830 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
831 o = (java_objectheader *) *((ptrint *) (sp + 4 * 8));
832 mcode = *((u4 *) (sp + 3 * 8));
833 uc = (unresolved_class *) *((ptrint *) (sp + 2 * 8));
835 /* calculate and set the new return address */
838 *((ptrint *) (sp + 5 * 8)) = (ptrint) ra;
840 PATCHER_MONITORENTER;
842 /* resolve the class */
844 if (!resolve_class(uc, resolveEager, false, &c)) {
850 /* patch back original code */
852 *((u4 *) ra) = mcode;
854 /* synchronize instruction cache */
856 asm_sync_instruction_cache();
858 PATCHER_MARK_PATCHED_MONITOREXIT;
862 #endif /* ENABLE_VERIFIER */
865 /* patcher_resolve_native ******************************************************
869 *******************************************************************************/
871 #if !defined(ENABLE_STATICVM)
872 bool patcher_resolve_native(u1 *sp)
875 java_objectheader *o;
882 /* get stuff from the stack */
884 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
885 o = (java_objectheader *) *((ptrint *) (sp + 4 * 8));
886 mcode = *((u4 *) (sp + 3 * 8));
887 m = (methodinfo *) *((ptrint *) (sp + 2 * 8));
888 disp = *((s4 *) (sp + 1 * 8));
889 pv = (u1 *) *((ptrint *) (sp + 0 * 8));
891 /* calculate and set the new return address */
894 *((ptrint *) (sp + 5 * 8)) = (ptrint) ra;
896 PATCHER_MONITORENTER;
898 /* resolve native function */
900 if (!(f = native_resolve_function(m))) {
906 /* patch back original code */
908 *((u4 *) ra) = mcode;
910 /* synchronize instruction cache */
912 asm_sync_instruction_cache();
914 /* patch native function pointer */
916 *((ptrint *) (pv + disp)) = (ptrint) f;
918 PATCHER_MARK_PATCHED_MONITOREXIT;
922 #endif /* !defined(ENABLE_STATICVM) */
926 * These are local overrides for various environment variables in Emacs.
927 * Please do not remove this and leave it at the end of the file, where
928 * Emacs will automagically detect them.
929 * ---------------------------------------------------------------------
932 * indent-tabs-mode: t
936 * vim:noexpandtab:sw=4:ts=4: