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 3883 2005-12-05 19:56:54Z twisti $
39 #include "mm/memory.h"
40 #include "native/native.h"
41 #include "vm/builtin.h"
44 #include "vm/initialize.h"
45 #include "vm/options.h"
46 #include "vm/references.h"
47 #include "vm/resolve.h"
48 #include "vm/jit/asmpart.h"
49 #include "vm/jit/patcher.h"
52 /* patcher_get_putstatic *******************************************************
56 <patched call position>
57 a73bff98 ldq t11,-104(pv)
58 a2590000 ldl a2,0(t11)
60 *******************************************************************************/
62 bool patcher_get_putstatic(u1 *sp)
72 /* get stuff from the stack */
74 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
75 o = (java_objectheader *) *((ptrint *) (sp + 4 * 8));
76 mcode = *((u4 *) (sp + 3 * 8));
77 uf = (unresolved_field *) *((ptrint *) (sp + 2 * 8));
78 disp = *((s4 *) (sp + 1 * 8));
79 pv = (u1 *) *((ptrint *) (sp + 0 * 8));
81 /* calculate and set the new return address */
84 *((ptrint *) (sp + 5 * 8)) = (ptrint) ra;
88 /* get the fieldinfo */
90 if (!(fi = resolve_field_eager(uf))) {
96 /* check if the field's class is initialized */
98 if (!(fi->class->state & CLASS_INITIALIZED)) {
99 if (!initialize_class(fi->class)) {
106 /* patch back original code */
108 *((u4 *) ra) = mcode;
110 /* synchronize instruction cache */
112 asm_sync_instruction_cache();
114 /* patch the field value's address */
116 *((ptrint *) (pv + disp)) = (ptrint) &(fi->value);
118 PATCHER_MARK_PATCHED_MONITOREXIT;
124 /* patcher_get_putfield ********************************************************
128 <patched call position>
129 a2af0020 ldl a5,32(s6)
131 *******************************************************************************/
133 bool patcher_get_putfield(u1 *sp)
136 java_objectheader *o;
138 unresolved_field *uf;
141 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
142 o = (java_objectheader *) *((ptrint *) (sp + 4 * 8));
143 mcode = *((u4 *) (sp + 3 * 8));
144 uf = (unresolved_field *) *((ptrint *) (sp + 2 * 8));
146 /* calculate and set the new return address */
149 *((ptrint *) (sp + 5 * 8)) = (ptrint) ra;
151 PATCHER_MONITORENTER;
153 /* get the fieldinfo */
155 if (!(fi = resolve_field_eager(uf))) {
161 /* patch back original code */
163 *((u4 *) ra) = mcode;
165 /* if we show disassembly, we have to skip the nop */
167 if (opt_showdisassemble)
170 /* patch the field's offset */
172 *((u4 *) ra) |= (s2) (fi->offset & 0x0000ffff);
174 /* synchronize instruction cache */
176 asm_sync_instruction_cache();
178 PATCHER_MARK_PATCHED_MONITOREXIT;
184 /* patcher_aconst **************************************************************
188 <patched call postition>
189 a61bff80 ldq a0,-128(pv)
191 *******************************************************************************/
193 bool patcher_aconst(u1 *sp)
196 java_objectheader *o;
198 constant_classref *cr;
203 /* get stuff from the stack */
205 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
206 o = (java_objectheader *) *((ptrint *) (sp + 4 * 8));
207 mcode = *((u4 *) (sp + 3 * 8));
208 cr = (constant_classref *) *((ptrint *) (sp + 2 * 8));
209 disp = *((s4 *) (sp + 1 * 8));
210 pv = (u1 *) *((ptrint *) (sp + 0 * 8));
212 /* calculate and set the new return address */
215 *((ptrint *) (sp + 5 * 8)) = (ptrint) ra;
217 PATCHER_MONITORENTER;
219 /* get the classinfo */
221 if (!(c = resolve_classref_eager(cr))) {
227 /* patch back original code */
229 *((u4 *) ra) = mcode;
231 /* synchronize instruction cache */
233 asm_sync_instruction_cache();
235 /* patch the classinfo pointer */
237 *((ptrint *) (pv + disp)) = (ptrint) c;
239 PATCHER_MARK_PATCHED_MONITOREXIT;
245 /* patcher_builtin_multianewarray **********************************************
249 <patched call position>
250 a63bff80 ldq a1,-128(pv)
252 a77bff78 ldq pv,-136(pv)
255 *******************************************************************************/
257 bool patcher_builtin_multianewarray(u1 *sp)
260 java_objectheader *o;
262 constant_classref *cr;
267 /* get stuff from the stack */
269 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
270 o = (java_objectheader *) *((ptrint *) (sp + 4 * 8));
271 mcode = *((u4 *) (sp + 3 * 8));
272 cr = (constant_classref *) *((ptrint *) (sp + 2 * 8));
273 disp = *((s4 *) (sp + 1 * 8));
274 pv = (u1 *) *((ptrint *) (sp + 0 * 8));
276 /* calculate and set the new return address */
279 *((ptrint *) (sp + 5 * 8)) = (ptrint) ra;
281 PATCHER_MONITORENTER;
283 /* get the classinfo */
285 if (!(c = resolve_classref_eager(cr))) {
291 /* patch back original code */
293 *((u4 *) ra) = mcode;
295 /* synchronize instruction cache */
297 asm_sync_instruction_cache();
299 /* patch the classinfo pointer */
301 *((ptrint *) (pv + disp)) = (ptrint) c;
303 PATCHER_MARK_PATCHED_MONITOREXIT;
309 /* patcher_builtin_arraycheckcast **********************************************
313 <patched call position>
314 a63bfe60 ldq a1,-416(pv)
315 a77bfe58 ldq pv,-424(pv)
318 *******************************************************************************/
320 bool patcher_builtin_arraycheckcast(u1 *sp)
323 java_objectheader *o;
325 constant_classref *cr;
330 /* get stuff from the stack */
332 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
333 o = (java_objectheader *) *((ptrint *) (sp + 4 * 8));
334 mcode = *((u4 *) (sp + 3 * 8));
335 cr = (constant_classref *) *((ptrint *) (sp + 2 * 8));
336 disp = *((s4 *) (sp + 1 * 8));
337 pv = (u1 *) *((ptrint *) (sp + 0 * 8));
339 /* calculate and set the new return address */
342 *((ptrint *) (sp + 5 * 8)) = (ptrint) ra;
344 PATCHER_MONITORENTER;
346 /* get the classinfo */
348 if (!(c = resolve_classref_eager(cr))) {
354 /* patch back original code */
356 *((u4 *) ra) = mcode;
358 /* synchronize instruction cache */
360 asm_sync_instruction_cache();
362 /* patch the classinfo pointer */
364 *((ptrint *) (pv + disp)) = (ptrint) c;
366 PATCHER_MARK_PATCHED_MONITOREXIT;
372 /* patcher_invokestatic_special ************************************************
376 <patched call position>
377 a77bffa8 ldq pv,-88(pv)
380 ******************************************************************************/
382 bool patcher_invokestatic_special(u1 *sp)
385 java_objectheader *o;
387 unresolved_method *um;
392 /* get stuff from the stack */
394 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
395 o = (java_objectheader *) *((ptrint *) (sp + 4 * 8));
396 mcode = *((u4 *) (sp + 3 * 8));
397 um = (unresolved_method *) *((ptrint *) (sp + 2 * 8));
398 disp = *((s4 *) (sp + 1 * 8));
399 pv = (u1 *) *((ptrint *) (sp + 0 * 8));
401 /* calculate and set the new return address */
404 *((ptrint *) (sp + 5 * 8)) = (ptrint) ra;
406 PATCHER_MONITORENTER;
408 /* get the fieldinfo */
410 if (!(m = resolve_method_eager(um))) {
416 /* patch back original code */
418 *((u4 *) ra) = mcode;
420 /* synchronize instruction cache */
422 asm_sync_instruction_cache();
424 /* patch stubroutine */
426 *((ptrint *) (pv + disp)) = (ptrint) m->stubroutine;
428 PATCHER_MARK_PATCHED_MONITOREXIT;
434 /* patcher_invokevirtual *******************************************************
438 <patched call position>
439 a7900000 ldq at,0(a0)
440 a77c0100 ldq pv,256(at)
443 *******************************************************************************/
445 bool patcher_invokevirtual(u1 *sp)
448 java_objectheader *o;
450 unresolved_method *um;
453 /* get stuff from the stack */
455 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
456 o = (java_objectheader *) *((ptrint *) (sp + 4 * 8));
457 mcode = *((u4 *) (sp + 3 * 8));
458 um = (unresolved_method *) *((ptrint *) (sp + 2 * 8));
460 /* calculate and set the new return address */
463 *((ptrint *) (sp + 5 * 8)) = (ptrint) ra;
465 PATCHER_MONITORENTER;
467 /* get the fieldinfo */
469 if (!(m = resolve_method_eager(um))) {
475 /* patch back original code */
477 *((u4 *) ra) = mcode;
479 /* if we show disassembly, we have to skip the nop */
481 if (opt_showdisassemble)
484 /* patch vftbl index */
486 *((s4 *) (ra + 4)) |= (s4) ((OFFSET(vftbl_t, table[0]) +
487 sizeof(methodptr) * m->vftblindex) & 0x0000ffff);
489 /* synchronize instruction cache */
491 asm_sync_instruction_cache();
493 PATCHER_MARK_PATCHED_MONITOREXIT;
499 /* patcher_invokeinterface *****************************************************
503 <patched call position>
504 a7900000 ldq at,0(a0)
505 a79cffa0 ldq at,-96(at)
506 a77c0018 ldq pv,24(at)
509 *******************************************************************************/
511 bool patcher_invokeinterface(u1 *sp)
514 java_objectheader *o;
516 unresolved_method *um;
519 /* get stuff from the stack */
521 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
522 o = (java_objectheader *) *((ptrint *) (sp + 4 * 8));
523 mcode = *((u4 *) (sp + 3 * 8));
524 um = (unresolved_method *) *((ptrint *) (sp + 2 * 8));
526 /* calculate and set the new return address */
529 *((ptrint *) (sp + 5 * 8)) = (ptrint) ra;
531 PATCHER_MONITORENTER;
533 /* get the fieldinfo */
535 if (!(m = resolve_method_eager(um))) {
541 /* patch back original code */
543 *((u4 *) ra) = mcode;
545 /* if we show disassembly, we have to skip the nop */
547 if (opt_showdisassemble)
550 /* patch interfacetable index */
552 *((s4 *) (ra + 4)) |= (s4) ((OFFSET(vftbl_t, interfacetable[0]) -
553 sizeof(methodptr*) * m->class->index) & 0x0000ffff);
555 /* patch method offset */
557 *((s4 *) (ra + 4 + 4)) |=
558 (s4) ((sizeof(methodptr) * (m - m->class->methods)) & 0x0000ffff);
560 /* synchronize instruction cache */
562 asm_sync_instruction_cache();
564 PATCHER_MARK_PATCHED_MONITOREXIT;
570 /* patcher_checkcast_instanceof_flags ******************************************
574 <patched call position>
576 *******************************************************************************/
578 bool patcher_checkcast_instanceof_flags(u1 *sp)
581 java_objectheader *o;
583 constant_classref *cr;
588 /* get stuff from the stack */
590 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
591 o = (java_objectheader *) *((ptrint *) (sp + 4 * 8));
592 mcode = *((u4 *) (sp + 3 * 8));
593 cr = (constant_classref *) *((ptrint *) (sp + 2 * 8));
594 disp = *((s4 *) (sp + 1 * 8));
595 pv = (u1 *) *((ptrint *) (sp + 0 * 8));
597 /* calculate and set the new return address */
600 *((ptrint *) (sp + 5 * 8)) = (ptrint) ra;
602 PATCHER_MONITORENTER;
604 /* get the fieldinfo */
606 if (!(c = resolve_classref_eager(cr))) {
612 /* patch back original code */
614 *((u4 *) ra) = mcode;
616 /* synchronize instruction cache */
618 asm_sync_instruction_cache();
620 /* patch class flags */
622 *((s4 *) (pv + disp)) = (s4) c->flags;
624 PATCHER_MARK_PATCHED_MONITOREXIT;
630 /* patcher_checkcast_instanceof_interface **************************************
634 <patched call position>
635 a78e0000 ldq at,0(s5)
636 a3bc001c ldl gp,28(at)
637 23bdfffd lda gp,-3(gp)
638 efa0002e ble gp,0x00000200002bf6b0
639 a7bcffe8 ldq gp,-24(at)
641 *******************************************************************************/
643 bool patcher_checkcast_instanceof_interface(u1 *sp)
646 java_objectheader *o;
648 constant_classref *cr;
651 /* get stuff from the stack */
653 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
654 o = (java_objectheader *) *((ptrint *) (sp + 4 * 8));
655 mcode = *((u4 *) (sp + 3 * 8));
656 cr = (constant_classref *) *((ptrint *) (sp + 2 * 8));
658 /* calculate and set the new return address */
661 *((ptrint *) (sp + 5 * 8)) = (ptrint) ra;
663 PATCHER_MONITORENTER;
665 /* get the fieldinfo */
667 if (!(c = resolve_classref_eager(cr))) {
673 /* patch back original code */
675 *((u4 *) ra) = mcode;
677 /* if we show disassembly, we have to skip the nop */
679 if (opt_showdisassemble)
682 /* patch super class index */
684 *((s4 *) (ra + 2 * 4)) |= (s4) (-(c->index) & 0x0000ffff);
686 *((s4 *) (ra + 4 * 4)) |= (s4) ((OFFSET(vftbl_t, interfacetable[0]) -
687 c->index * sizeof(methodptr*)) & 0x0000ffff);
689 /* synchronize instruction cache */
691 asm_sync_instruction_cache();
693 PATCHER_MARK_PATCHED_MONITOREXIT;
699 /* patcher_checkcast_instanceof_class ******************************************
703 <patched call position>
704 a7940000 ldq at,0(a4)
705 a7bbff28 ldq gp,-216(pv)
707 *******************************************************************************/
709 bool patcher_checkcast_instanceof_class(u1 *sp)
712 java_objectheader *o;
714 constant_classref *cr;
719 /* get stuff from the stack */
721 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
722 o = (java_objectheader *) *((ptrint *) (sp + 4 * 8));
723 mcode = *((u4 *) (sp + 3 * 8));
724 cr = (constant_classref *) *((ptrint *) (sp + 2 * 8));
725 disp = *((s4 *) (sp + 1 * 8));
726 pv = (u1 *) *((ptrint *) (sp + 0 * 8));
728 /* calculate and set the new return address */
731 *((ptrint *) (sp + 5 * 8)) = (ptrint) ra;
733 PATCHER_MONITORENTER;
735 /* get the fieldinfo */
737 if (!(c = resolve_classref_eager(cr))) {
743 /* patch back original code */
745 *((u4 *) ra) = mcode;
747 /* synchronize instruction cache */
749 asm_sync_instruction_cache();
751 /* patch super class' vftbl */
753 *((ptrint *) (pv + disp)) = (ptrint) c->vftbl;
755 PATCHER_MARK_PATCHED_MONITOREXIT;
761 /* patcher_clinit **************************************************************
765 *******************************************************************************/
767 bool patcher_clinit(u1 *sp)
770 java_objectheader *o;
774 /* get stuff from the stack */
776 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
777 o = (java_objectheader *) *((ptrint *) (sp + 4 * 8));
778 mcode = *((u4 *) (sp + 3 * 8));
779 c = (classinfo *) *((ptrint *) (sp + 2 * 8));
781 /* calculate and set the new return address */
784 *((ptrint *) (sp + 5 * 8)) = (ptrint) ra;
786 PATCHER_MONITORENTER;
788 /* check if the class is initialized */
790 if (!(c->state & CLASS_INITIALIZED)) {
791 if (!initialize_class(c)) {
798 /* patch back original code */
800 *((u4 *) ra) = mcode;
802 /* synchronize instruction cache */
804 asm_sync_instruction_cache();
806 PATCHER_MARK_PATCHED_MONITOREXIT;
812 /* patcher_athrow_areturn ******************************************************
816 <patched call position>
818 *******************************************************************************/
820 #ifdef ENABLE_VERIFIER
821 bool patcher_athrow_areturn(u1 *sp)
824 java_objectheader *o;
826 unresolved_class *uc;
829 /* get stuff from the stack */
831 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
832 o = (java_objectheader *) *((ptrint *) (sp + 4 * 8));
833 mcode = *((u4 *) (sp + 3 * 8));
834 uc = (unresolved_class *) *((ptrint *) (sp + 2 * 8));
836 /* calculate and set the new return address */
839 *((ptrint *) (sp + 5 * 8)) = (ptrint) ra;
841 PATCHER_MONITORENTER;
843 /* resolve the class */
845 if (!resolve_class(uc, resolveEager, false, &c)) {
851 /* patch back original code */
853 *((u4 *) ra) = mcode;
855 /* synchronize instruction cache */
857 asm_sync_instruction_cache();
859 PATCHER_MARK_PATCHED_MONITOREXIT;
863 #endif /* ENABLE_VERIFIER */
866 /* patcher_resolve_native ******************************************************
870 *******************************************************************************/
872 #if !defined(ENABLE_STATICVM)
873 bool patcher_resolve_native(u1 *sp)
876 java_objectheader *o;
883 /* get stuff from the stack */
885 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
886 o = (java_objectheader *) *((ptrint *) (sp + 4 * 8));
887 mcode = *((u4 *) (sp + 3 * 8));
888 m = (methodinfo *) *((ptrint *) (sp + 2 * 8));
889 disp = *((s4 *) (sp + 1 * 8));
890 pv = (u1 *) *((ptrint *) (sp + 0 * 8));
892 /* calculate and set the new return address */
895 *((ptrint *) (sp + 5 * 8)) = (ptrint) ra;
897 PATCHER_MONITORENTER;
899 /* resolve native function */
901 if (!(f = native_resolve_function(m))) {
907 /* patch back original code */
909 *((u4 *) ra) = mcode;
911 /* synchronize instruction cache */
913 asm_sync_instruction_cache();
915 /* patch native function pointer */
917 *((ptrint *) (pv + disp)) = (ptrint) f;
919 PATCHER_MARK_PATCHED_MONITOREXIT;
923 #endif /* !defined(ENABLE_STATICVM) */
927 * These are local overrides for various environment variables in Emacs.
928 * Please do not remove this and leave it at the end of the file, where
929 * Emacs will automagically detect them.
930 * ---------------------------------------------------------------------
933 * indent-tabs-mode: t
937 * vim:noexpandtab:sw=4:ts=4: