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 3108 2005-07-24 23:04:48Z twisti $
36 #include "vm/jit/alpha/types.h"
38 #include "mm/memory.h"
39 #include "native/native.h"
40 #include "vm/builtin.h"
42 #include "vm/initialize.h"
43 #include "vm/options.h"
44 #include "vm/references.h"
45 #include "vm/jit/asmpart.h"
46 #include "vm/jit/helper.h"
47 #include "vm/jit/patcher.h"
50 /* patcher_get_putstatic *******************************************************
54 <patched call position>
55 a73bff98 ldq t11,-104(pv)
56 a2590000 ldl a2,0(t11)
58 *******************************************************************************/
60 bool patcher_get_putstatic(u1 *sp)
70 /* get stuff from the stack */
72 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
73 o = (java_objectheader *) *((ptrint *) (sp + 4 * 8));
74 mcode = *((u4 *) (sp + 3 * 8));
75 uf = (unresolved_field *) *((ptrint *) (sp + 2 * 8));
76 disp = *((s4 *) (sp + 1 * 8));
77 pv = (u1 *) *((ptrint *) (sp + 0 * 8));
79 /* calculate and set the new return address */
82 *((ptrint *) (sp + 5 * 8)) = (ptrint) ra;
86 /* get the fieldinfo */
88 if (!(fi = helper_resolve_fieldinfo(uf))) {
94 /* check if the field's class is initialized */
96 if (!fi->class->initialized) {
97 if (!initialize_class(fi->class)) {
104 /* patch back original code */
106 *((u4 *) ra) = mcode;
108 /* if we show disassembly, we have to skip the nop */
110 if (opt_showdisassemble)
113 /* patch the field value's address */
115 *((ptrint *) (pv + disp)) = (ptrint) &(fi->value);
117 /* synchronize instruction cache */
119 asm_sync_instruction_cache();
121 PATCHER_MARK_PATCHED_MONITOREXIT;
127 /* patcher_get_putfield ********************************************************
131 <patched call position>
132 a2af0020 ldl a5,32(s6)
134 *******************************************************************************/
136 bool patcher_get_putfield(u1 *sp)
139 java_objectheader *o;
141 unresolved_field *uf;
144 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
145 o = (java_objectheader *) *((ptrint *) (sp + 4 * 8));
146 mcode = *((u4 *) (sp + 3 * 8));
147 uf = (unresolved_field *) *((ptrint *) (sp + 2 * 8));
149 /* calculate and set the new return address */
152 *((ptrint *) (sp + 5 * 8)) = (ptrint) ra;
154 PATCHER_MONITORENTER;
156 /* get the fieldinfo */
158 if (!(fi = helper_resolve_fieldinfo(uf))) {
164 /* patch back original code */
166 *((u4 *) ra) = mcode;
168 /* if we show disassembly, we have to skip the nop */
170 if (opt_showdisassemble)
173 /* patch the field's offset */
175 *((u4 *) ra) |= (s2) (fi->offset & 0x0000ffff);
177 /* synchronize instruction cache */
179 asm_sync_instruction_cache();
181 PATCHER_MARK_PATCHED_MONITOREXIT;
187 /* patcher_builtin_new *********************************************************
191 a61bff80 ldq a0,-128(pv)
192 <patched call postition>
193 a77bff78 ldq pv,-136(pv)
196 NOTICE: Only the displacement for the function address is passed,
197 but the address of the classinfo pointer is one below (above, in
198 addresses speaking). This is for sure.
200 *******************************************************************************/
202 bool patcher_builtin_new(u1 *sp)
205 java_objectheader *o;
207 constant_classref *cr;
212 /* get stuff from the stack */
214 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
215 o = (java_objectheader *) *((ptrint *) (sp + 4 * 8));
216 mcode = *((u4 *) (sp + 3 * 8));
217 cr = (constant_classref *) *((ptrint *) (sp + 2 * 8));
218 disp = *((s4 *) (sp + 1 * 8));
219 pv = (u1 *) *((ptrint *) (sp + 0 * 8));
221 /* calculate and set the new return address */
224 *((ptrint *) (sp + 5 * 8)) = (ptrint) ra;
226 PATCHER_MONITORENTER;
228 /* get the classinfo */
230 if (!(c = helper_resolve_classinfo(cr))) {
236 /* patch back original code */
238 *((u4 *) (ra + 4)) = mcode;
240 /* patch the classinfo pointer */
242 *((ptrint *) (pv + (disp + SIZEOF_VOID_P))) = (ptrint) c;
244 /* if we show disassembly, we have to skip the nop */
246 if (opt_showdisassemble)
249 /* patch new function address */
251 *((ptrint *) (pv + disp)) = (ptrint) BUILTIN_new;
253 /* synchronize instruction cache */
255 asm_sync_instruction_cache();
257 PATCHER_MARK_PATCHED_MONITOREXIT;
263 /* patcher_builtin_newarray ****************************************************
267 a63bff88 ldq a1,-120(pv)
268 <patched call position>
269 a77bff80 ldq pv,-128(pv)
272 NOTICE: Only the displacement for the function address is passed,
273 but the address of the classinfo pointer is one below (above, in
274 addresses speaking). This is for sure.
276 *******************************************************************************/
278 bool patcher_builtin_newarray(u1 *sp)
281 java_objectheader *o;
283 constant_classref *cr;
288 /* get stuff from the stack */
290 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
291 o = (java_objectheader *) *((ptrint *) (sp + 4 * 8));
292 mcode = *((u4 *) (sp + 3 * 8));
293 cr = (constant_classref *) *((ptrint *) (sp + 2 * 8));
294 disp = *((s4 *) (sp + 1 * 8));
295 pv = (u1 *) *((ptrint *) (sp + 0 * 8));
297 /* calculate and set the new return address */
300 *((ptrint *) (sp + 5 * 8)) = (ptrint) ra;
302 PATCHER_MONITORENTER;
304 /* get the classinfo */
306 if (!(c = helper_resolve_classinfo(cr))) {
312 /* patch back original code */
314 *((u4 *) (ra + 4)) = mcode;
316 /* patch the class' vftbl pointer */
318 *((ptrint *) (pv + (disp + SIZEOF_VOID_P))) = (ptrint) c->vftbl;
320 /* if we show disassembly, we have to skip the nop */
322 if (opt_showdisassemble)
325 /* patch new function address */
327 *((ptrint *) (pv + disp)) = (ptrint) BUILTIN_newarray;
329 /* synchronize instruction cache */
331 asm_sync_instruction_cache();
333 PATCHER_MARK_PATCHED_MONITOREXIT;
339 /* patcher_builtin_multianewarray **********************************************
343 <patched call position>
344 a63bff80 ldq a1,-128(pv)
346 a77bff78 ldq pv,-136(pv)
349 *******************************************************************************/
351 bool patcher_builtin_multianewarray(u1 *sp)
354 java_objectheader *o;
356 constant_classref *cr;
361 /* get stuff from the stack */
363 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
364 o = (java_objectheader *) *((ptrint *) (sp + 4 * 8));
365 mcode = *((u4 *) (sp + 3 * 8));
366 cr = (constant_classref *) *((ptrint *) (sp + 2 * 8));
367 disp = *((s4 *) (sp + 1 * 8));
368 pv = (u1 *) *((ptrint *) (sp + 0 * 8));
370 /* calculate and set the new return address */
373 *((ptrint *) (sp + 5 * 8)) = (ptrint) ra;
375 PATCHER_MONITORENTER;
377 /* get the classinfo */
379 if (!(c = helper_resolve_classinfo(cr))) {
385 /* patch back original code */
387 *((u4 *) ra) = mcode;
389 /* if we show disassembly, we have to skip the nop */
391 if (opt_showdisassemble)
394 /* patch the class' vftbl pointer */
396 *((ptrint *) (pv + disp)) = (ptrint) c->vftbl;
398 /* synchronize instruction cache */
400 asm_sync_instruction_cache();
402 PATCHER_MARK_PATCHED_MONITOREXIT;
408 /* patcher_builtin_arraycheckcast **********************************************
412 <patched call position>
413 a63bfe60 ldq a1,-416(pv)
414 a77bfe58 ldq pv,-424(pv)
417 NOTICE: Only the displacement of the vftbl pointer address is
418 passed, but the address of the function pointer is one above
419 (below, in addresses speaking). This is for sure.
421 *******************************************************************************/
423 bool patcher_builtin_arraycheckcast(u1 *sp)
426 java_objectheader *o;
428 constant_classref *cr;
433 /* get stuff from the stack */
435 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
436 o = (java_objectheader *) *((ptrint *) (sp + 4 * 8));
437 mcode = *((u4 *) (sp + 3 * 8));
438 cr = (constant_classref *) *((ptrint *) (sp + 2 * 8));
439 disp = *((s4 *) (sp + 1 * 8));
440 pv = (u1 *) *((ptrint *) (sp + 0 * 8));
442 /* calculate and set the new return address */
445 *((ptrint *) (sp + 5 * 8)) = (ptrint) ra;
447 PATCHER_MONITORENTER;
449 /* get the classinfo */
451 if (!(c = helper_resolve_classinfo(cr))) {
457 /* patch back original code */
459 *((u4 *) ra) = mcode;
461 /* if we show disassembly, we have to skip the nop */
463 if (opt_showdisassemble)
466 /* patch the class' vftbl pointer */
468 *((ptrint *) (pv + disp)) = (ptrint) c->vftbl;
470 /* patch new function address */
472 *((ptrint *) (pv + (disp - SIZEOF_VOID_P))) =
473 (ptrint) BUILTIN_arraycheckcast;
475 /* synchronize instruction cache */
477 asm_sync_instruction_cache();
479 PATCHER_MARK_PATCHED_MONITOREXIT;
485 /* patcher_builtin_arrayinstanceof *********************************************
489 a63bfeb0 ldq a1,-336(pv)
490 <patched call position>
491 a77bfea8 ldq pv,-344(pv)
494 NOTICE: Only the displacement for the function address is passed,
495 but the address of the vftbl pointer is one below (above, in
496 addresses speaking). This is for sure.
498 *******************************************************************************/
500 bool patcher_builtin_arrayinstanceof(u1 *sp)
503 java_objectheader *o;
505 constant_classref *cr;
510 /* get stuff from the stack */
512 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
513 o = (java_objectheader *) *((ptrint *) (sp + 4 * 8));
514 mcode = *((u4 *) (sp + 3 * 8));
515 cr = (constant_classref *) *((ptrint *) (sp + 2 * 8));
516 disp = *((s4 *) (sp + 1 * 8));
517 pv = (u1 *) *((ptrint *) (sp + 0 * 8));
519 /* calculate and set the new return address */
522 *((ptrint *) (sp + 5 * 8)) = (ptrint) ra;
524 PATCHER_MONITORENTER;
526 /* get the classinfo */
528 if (!(c = helper_resolve_classinfo(cr))) {
534 /* patch back original code */
536 *((u4 *) (ra + 4)) = mcode;
538 /* patch the class' vftbl pointer */
540 *((ptrint *) (pv + (disp + SIZEOF_VOID_P))) = (ptrint) c->vftbl;
542 /* if we show disassembly, we have to skip the nop */
544 if (opt_showdisassemble)
547 /* patch new function address */
549 *((ptrint *) (pv + disp)) = (ptrint) BUILTIN_arrayinstanceof;
551 /* synchronize instruction cache */
553 asm_sync_instruction_cache();
555 PATCHER_MARK_PATCHED_MONITOREXIT;
561 /* patcher_invokestatic_special ************************************************
565 <patched call position>
566 a77bffa8 ldq pv,-88(pv)
569 ******************************************************************************/
571 bool patcher_invokestatic_special(u1 *sp)
574 java_objectheader *o;
576 unresolved_method *um;
581 /* get stuff from the stack */
583 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
584 o = (java_objectheader *) *((ptrint *) (sp + 4 * 8));
585 mcode = *((u4 *) (sp + 3 * 8));
586 um = (unresolved_method *) *((ptrint *) (sp + 2 * 8));
587 disp = *((s4 *) (sp + 1 * 8));
588 pv = (u1 *) *((ptrint *) (sp + 0 * 8));
590 /* calculate and set the new return address */
593 *((ptrint *) (sp + 5 * 8)) = (ptrint) ra;
595 PATCHER_MONITORENTER;
597 /* get the fieldinfo */
599 if (!(m = helper_resolve_methodinfo(um))) {
605 /* patch back original code */
607 *((u4 *) ra) = mcode;
609 /* if we show disassembly, we have to skip the nop */
611 if (opt_showdisassemble)
614 /* patch stubroutine */
616 *((ptrint *) (pv + disp)) = (ptrint) m->stubroutine;
618 /* synchronize instruction cache */
620 asm_sync_instruction_cache();
622 PATCHER_MARK_PATCHED_MONITOREXIT;
628 /* patcher_invokevirtual *******************************************************
632 <patched call position>
633 a7900000 ldq at,0(a0)
634 a77c0100 ldq pv,256(at)
637 *******************************************************************************/
639 bool patcher_invokevirtual(u1 *sp)
642 java_objectheader *o;
644 unresolved_method *um;
647 /* get stuff from the stack */
649 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
650 o = (java_objectheader *) *((ptrint *) (sp + 4 * 8));
651 mcode = *((u4 *) (sp + 3 * 8));
652 um = (unresolved_method *) *((ptrint *) (sp + 2 * 8));
654 /* calculate and set the new return address */
657 *((ptrint *) (sp + 5 * 8)) = (ptrint) ra;
659 PATCHER_MONITORENTER;
661 /* get the fieldinfo */
663 if (!(m = helper_resolve_methodinfo(um))) {
669 /* patch back original code */
671 *((u4 *) ra) = mcode;
673 /* if we show disassembly, we have to skip the nop */
675 if (opt_showdisassemble)
678 /* patch vftbl index */
680 *((s4 *) (ra + 4)) |= (s4) ((OFFSET(vftbl_t, table[0]) +
681 sizeof(methodptr) * m->vftblindex) & 0x0000ffff);
683 /* synchronize instruction cache */
685 asm_sync_instruction_cache();
687 PATCHER_MARK_PATCHED_MONITOREXIT;
693 /* patcher_invokeinterface *****************************************************
697 <patched call position>
698 a7900000 ldq at,0(a0)
699 a79cffa0 ldq at,-96(at)
700 a77c0018 ldq pv,24(at)
703 *******************************************************************************/
705 bool patcher_invokeinterface(u1 *sp)
708 java_objectheader *o;
710 unresolved_method *um;
713 /* get stuff from the stack */
715 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
716 o = (java_objectheader *) *((ptrint *) (sp + 4 * 8));
717 mcode = *((u4 *) (sp + 3 * 8));
718 um = (unresolved_method *) *((ptrint *) (sp + 2 * 8));
720 /* calculate and set the new return address */
723 *((ptrint *) (sp + 5 * 8)) = (ptrint) ra;
725 PATCHER_MONITORENTER;
727 /* get the fieldinfo */
729 if (!(m = helper_resolve_methodinfo(um))) {
735 /* patch back original code */
737 *((u4 *) ra) = mcode;
739 /* if we show disassembly, we have to skip the nop */
741 if (opt_showdisassemble)
744 /* patch interfacetable index */
746 *((s4 *) (ra + 4)) |= (s4) ((OFFSET(vftbl_t, interfacetable[0]) -
747 sizeof(methodptr*) * m->class->index) & 0x0000ffff);
749 /* patch method offset */
751 *((s4 *) (ra + 4 + 4)) |=
752 (s4) ((sizeof(methodptr) * (m - m->class->methods)) & 0x0000ffff);
754 /* synchronize instruction cache */
756 asm_sync_instruction_cache();
758 PATCHER_MARK_PATCHED_MONITOREXIT;
764 /* patcher_checkcast_instanceof_flags ******************************************
768 <patched call position>
770 *******************************************************************************/
772 bool patcher_checkcast_instanceof_flags(u1 *sp)
775 java_objectheader *o;
777 constant_classref *cr;
782 /* get stuff from the stack */
784 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
785 o = (java_objectheader *) *((ptrint *) (sp + 4 * 8));
786 mcode = *((u4 *) (sp + 3 * 8));
787 cr = (constant_classref *) *((ptrint *) (sp + 2 * 8));
788 disp = *((s4 *) (sp + 1 * 8));
789 pv = (u1 *) *((ptrint *) (sp + 0 * 8));
791 /* calculate and set the new return address */
794 *((ptrint *) (sp + 5 * 8)) = (ptrint) ra;
796 PATCHER_MONITORENTER;
798 /* get the fieldinfo */
800 if (!(c = helper_resolve_classinfo(cr))) {
806 /* patch back original code */
808 *((u4 *) ra) = mcode;
810 /* if we show disassembly, we have to skip the nop */
812 if (opt_showdisassemble)
815 /* patch class flags */
817 *((s4 *) (pv + disp)) = (s4) c->flags;
819 /* synchronize instruction cache */
821 asm_sync_instruction_cache();
823 PATCHER_MARK_PATCHED_MONITOREXIT;
829 /* patcher_checkcast_instanceof_interface **************************************
833 <patched call position>
834 a78e0000 ldq at,0(s5)
835 a3bc001c ldl gp,28(at)
836 23bdfffd lda gp,-3(gp)
837 efa0002e ble gp,0x00000200002bf6b0
838 a7bcffe8 ldq gp,-24(at)
840 *******************************************************************************/
842 bool patcher_checkcast_instanceof_interface(u1 *sp)
845 java_objectheader *o;
847 constant_classref *cr;
850 /* get stuff from the stack */
852 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
853 o = (java_objectheader *) *((ptrint *) (sp + 4 * 8));
854 mcode = *((u4 *) (sp + 3 * 8));
855 cr = (constant_classref *) *((ptrint *) (sp + 2 * 8));
857 /* calculate and set the new return address */
860 *((ptrint *) (sp + 5 * 8)) = (ptrint) ra;
862 PATCHER_MONITORENTER;
864 /* get the fieldinfo */
866 if (!(c = helper_resolve_classinfo(cr))) {
872 /* patch back original code */
874 *((u4 *) ra) = mcode;
876 /* if we show disassembly, we have to skip the nop */
878 if (opt_showdisassemble)
881 /* patch super class index */
883 *((s4 *) (ra + 2 * 4)) |= (s4) (-(c->index) & 0x0000ffff);
885 *((s4 *) (ra + 4 * 4)) |= (s4) ((OFFSET(vftbl_t, interfacetable[0]) -
886 c->index * sizeof(methodptr*)) & 0x0000ffff);
888 /* synchronize instruction cache */
890 asm_sync_instruction_cache();
892 PATCHER_MARK_PATCHED_MONITOREXIT;
898 /* patcher_checkcast_instanceof_class ******************************************
902 <patched call position>
903 a7940000 ldq at,0(a4)
904 a7bbff28 ldq gp,-216(pv)
906 *******************************************************************************/
908 bool patcher_checkcast_instanceof_class(u1 *sp)
911 java_objectheader *o;
913 constant_classref *cr;
918 /* get stuff from the stack */
920 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
921 o = (java_objectheader *) *((ptrint *) (sp + 4 * 8));
922 mcode = *((u4 *) (sp + 3 * 8));
923 cr = (constant_classref *) *((ptrint *) (sp + 2 * 8));
924 disp = *((s4 *) (sp + 1 * 8));
925 pv = (u1 *) *((ptrint *) (sp + 0 * 8));
927 /* calculate and set the new return address */
930 *((ptrint *) (sp + 5 * 8)) = (ptrint) ra;
932 PATCHER_MONITORENTER;
934 /* get the fieldinfo */
936 if (!(c = helper_resolve_classinfo(cr))) {
942 /* patch back original code */
944 *((u4 *) ra) = mcode;
946 /* if we show disassembly, we have to skip the nop */
948 if (opt_showdisassemble)
951 /* patch super class' vftbl */
953 *((ptrint *) (pv + disp)) = (ptrint) c->vftbl;
955 /* synchronize instruction cache */
957 asm_sync_instruction_cache();
959 PATCHER_MARK_PATCHED_MONITOREXIT;
965 /* patcher_clinit **************************************************************
969 *******************************************************************************/
971 bool patcher_clinit(u1 *sp)
974 java_objectheader *o;
978 /* get stuff from the stack */
980 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
981 o = (java_objectheader *) *((ptrint *) (sp + 4 * 8));
982 mcode = *((u4 *) (sp + 3 * 8));
983 c = (classinfo *) *((ptrint *) (sp + 2 * 8));
985 /* calculate and set the new return address */
988 *((ptrint *) (sp + 5 * 8)) = (ptrint) ra;
990 PATCHER_MONITORENTER;
992 /* check if the class is initialized */
994 if (!c->initialized) {
995 if (!initialize_class(c)) {
1002 /* patch back original code */
1004 *((u4 *) ra) = mcode;
1006 /* synchronize instruction cache */
1008 asm_sync_instruction_cache();
1010 PATCHER_MARK_PATCHED_MONITOREXIT;
1016 /* patcher_resolve_native ******************************************************
1020 *******************************************************************************/
1022 #if !defined(ENABLE_STATICVM)
1023 bool patcher_resolve_native(u1 *sp)
1026 java_objectheader *o;
1033 /* get stuff from the stack */
1035 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
1036 o = (java_objectheader *) *((ptrint *) (sp + 4 * 8));
1037 mcode = *((u4 *) (sp + 3 * 8));
1038 m = (methodinfo *) *((ptrint *) (sp + 2 * 8));
1039 disp = *((s4 *) (sp + 1 * 8));
1040 pv = (u1 *) *((ptrint *) (sp + 0 * 8));
1042 /* calculate and set the new return address */
1045 *((ptrint *) (sp + 5 * 8)) = (ptrint) ra;
1047 PATCHER_MONITORENTER;
1049 /* resolve native function */
1051 if (!(f = native_resolve_function(m))) {
1052 PATCHER_MONITOREXIT;
1057 /* patch back original code */
1059 *((u4 *) ra) = mcode;
1061 /* if we show disassembly, we have to skip the nop */
1063 if (opt_showdisassemble)
1066 /* patch native function pointer */
1068 *((ptrint *) (pv + disp)) = (ptrint) f;
1070 /* synchronize instruction cache */
1072 asm_sync_instruction_cache();
1074 PATCHER_MARK_PATCHED_MONITOREXIT;
1078 #endif /* !defined(ENABLE_STATICVM) */
1082 * These are local overrides for various environment variables in Emacs.
1083 * Please do not remove this and leave it at the end of the file, where
1084 * Emacs will automagically detect them.
1085 * ---------------------------------------------------------------------
1088 * indent-tabs-mode: t
1092 * vim:noexpandtab:sw=4:ts=4: