1 /* src/vm/jit/powerpc/patcher.c - PowerPC code patching functions
3 Copyright (C) 1996-2005, 2006 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
25 Contact: cacao@cacaojvm.org
27 Authors: Christian Thalinger
31 $Id: patcher.c 4708 2006-03-30 10:10:07Z 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/resolve.h"
47 #include "vm/references.h"
48 #include "vm/jit/asmpart.h"
49 #include "vm/jit/patcher.h"
52 /* patcher_get_putstatic *******************************************************
56 <patched call position>
57 816dffc8 lwz r11,-56(r13)
58 80ab0000 lwz r5,0(r11)
60 *******************************************************************************/
62 bool patcher_get_putstatic(u1 *sp)
72 /* get stuff from the stack */
74 ra = (u1 *) *((ptrint *) (sp + 5 * 4));
75 o = (java_objectheader *) *((ptrint *) (sp + 4 * 4));
76 mcode = *((u4 *) (sp + 3 * 4));
77 uf = (unresolved_field *) *((ptrint *) (sp + 2 * 4));
78 disp = *((s4 *) (sp + 1 * 4));
79 pv = (u1 *) *((ptrint *) (sp + 0 * 4));
83 /* get the fieldinfo */
85 if (!(fi = resolve_field_eager(uf))) {
91 /* check if the field's class is initialized */
93 if (!(fi->class->state & CLASS_INITIALIZED)) {
94 if (!initialize_class(fi->class)) {
101 /* patch back original code */
103 *((u4 *) ra) = mcode;
105 /* synchronize instruction cache */
107 md_icacheflush(ra, 4);
109 /* patch the field value's address */
111 *((ptrint *) (pv + disp)) = (ptrint) &(fi->value);
113 /* synchronize data cache */
115 md_dcacheflush(pv + disp, SIZEOF_VOID_P);
117 PATCHER_MARK_PATCHED_MONITOREXIT;
123 /* patcher_get_putfield ********************************************************
127 <patched call position>
128 811f0014 lwz r8,20(r31)
130 *******************************************************************************/
132 bool patcher_get_putfield(u1 *sp)
135 java_objectheader *o;
137 unresolved_field *uf;
141 ra = (u1 *) *((ptrint *) (sp + 5 * 4));
142 o = (java_objectheader *) *((ptrint *) (sp + 4 * 4));
143 mcode = *((u4 *) (sp + 3 * 4));
144 uf = (unresolved_field *) *((ptrint *) (sp + 2 * 4));
145 pv = (u1 *) *((ptrint *) (sp + 1 * 4));
147 PATCHER_MONITORENTER;
149 /* get the fieldinfo */
151 if (!(fi = resolve_field_eager(uf))) {
157 /* patch back original code */
159 *((u4 *) ra) = mcode;
161 /* if we show disassembly, we have to skip the nop */
163 if (opt_showdisassemble)
166 /* patch the field's offset */
168 if (fi->type == TYPE_LNG) {
171 /* If the field has type long, we have to patch two
172 instructions. But we have to check which instruction is
173 first. We do that with the offset of the first
176 disp = *((u4 *) (ra + 0));
178 #if WORDS_BIGENDIAN == 1
180 *((u4 *) (ra + 0)) |= (s2) ((fi->offset + 4) & 0x0000ffff);
181 *((u4 *) (ra + 4)) |= (s2) ((fi->offset + 0) & 0x0000ffff);
184 *((u4 *) (ra + 0)) |= (s2) ((fi->offset + 0) & 0x0000ffff);
185 *((u4 *) (ra + 4)) |= (s2) ((fi->offset + 4) & 0x0000ffff);
191 *((u4 *) ra) |= (s2) (fi->offset & 0x0000ffff);
194 /* synchronize instruction cache */
196 md_icacheflush(ra, 8);
198 PATCHER_MARK_PATCHED_MONITOREXIT;
204 /* patcher_aconst **************************************************************
208 <patched call postition>
209 806dffc4 lwz r3,-60(r13)
210 81adffc0 lwz r13,-64(r13)
214 *******************************************************************************/
216 bool patcher_aconst(u1 *sp)
219 java_objectheader *o;
221 constant_classref *cr;
226 /* get stuff from the stack */
228 ra = (u1 *) *((ptrint *) (sp + 5 * 4));
229 o = (java_objectheader *) *((ptrint *) (sp + 4 * 4));
230 mcode = *((u4 *) (sp + 3 * 4));
231 cr = (constant_classref *) *((ptrint *) (sp + 2 * 4));
232 disp = *((s4 *) (sp + 1 * 4));
233 pv = (u1 *) *((ptrint *) (sp + 0 * 4));
235 PATCHER_MONITORENTER;
237 /* get the classinfo */
239 if (!(c = resolve_classref_eager(cr))) {
245 /* patch back original code */
247 *((u4 *) ra) = mcode;
249 /* synchronize instruction cache */
251 md_icacheflush(ra, 4);
253 /* patch the classinfo pointer */
255 *((ptrint *) (pv + disp)) = (ptrint) c;
257 /* synchronize data cache */
259 md_dcacheflush(pv + disp, SIZEOF_VOID_P);
261 PATCHER_MARK_PATCHED_MONITOREXIT;
267 /* patcher_builtin_multianewarray **********************************************
271 <patched call position>
272 808dffc0 lwz r4,-64(r13)
273 38a10038 addi r5,r1,56
274 81adffbc lwz r13,-68(r13)
278 *******************************************************************************/
280 bool patcher_builtin_multianewarray(u1 *sp)
283 java_objectheader *o;
285 constant_classref *cr;
290 /* get stuff from the stack */
292 ra = (u1 *) *((ptrint *) (sp + 5 * 4));
293 o = (java_objectheader *) *((ptrint *) (sp + 4 * 4));
294 mcode = *((u4 *) (sp + 3 * 4));
295 cr = (constant_classref *) *((ptrint *) (sp + 2 * 4));
296 disp = *((s4 *) (sp + 1 * 4));
297 pv = (u1 *) *((ptrint *) (sp + 0 * 4));
299 PATCHER_MONITORENTER;
301 /* get the classinfo */
303 if (!(c = resolve_classref_eager(cr))) {
309 /* patch back original code */
311 *((u4 *) ra) = mcode;
313 /* synchronize instruction cache */
315 md_icacheflush(ra, 4);
317 /* patch the classinfo pointer */
319 *((ptrint *) (pv + disp)) = (ptrint) c;
321 /* synchronize data cache */
323 md_dcacheflush(pv + disp, SIZEOF_VOID_P);
325 PATCHER_MARK_PATCHED_MONITOREXIT;
331 /* patcher_builtin_arraycheckcast **********************************************
335 <patched call position>
336 808dffd8 lwz r4,-40(r13)
337 81adffd4 lwz r13,-44(r13)
341 *******************************************************************************/
343 bool patcher_builtin_arraycheckcast(u1 *sp)
346 java_objectheader *o;
348 constant_classref *cr;
353 /* get stuff from the stack */
355 ra = (u1 *) *((ptrint *) (sp + 5 * 4));
356 o = (java_objectheader *) *((ptrint *) (sp + 4 * 4));
357 mcode = *((u4 *) (sp + 3 * 4));
358 cr = (constant_classref *) *((ptrint *) (sp + 2 * 4));
359 disp = *((s4 *) (sp + 1 * 4));
360 pv = (u1 *) *((ptrint *) (sp + 0 * 4));
362 PATCHER_MONITORENTER;
364 /* get the classinfo */
366 if (!(c = resolve_classref_eager(cr))) {
372 /* patch back original code */
374 *((u4 *) ra) = mcode;
376 /* synchronize instruction cache */
378 md_icacheflush(ra, 4);
380 /* patch the classinfo pointer */
382 *((ptrint *) (pv + disp)) = (ptrint) c;
384 /* synchronize data cache */
386 md_dcacheflush(pv + disp, SIZEOF_VOID_P);
388 PATCHER_MARK_PATCHED_MONITOREXIT;
394 /* patcher_invokestatic_special ************************************************
398 <patched call position>
399 81adffd8 lwz r13,-40(r13)
403 ******************************************************************************/
405 bool patcher_invokestatic_special(u1 *sp)
408 java_objectheader *o;
410 unresolved_method *um;
415 /* get stuff from the stack */
417 ra = (u1 *) *((ptrint *) (sp + 5 * 4));
418 o = (java_objectheader *) *((ptrint *) (sp + 4 * 4));
419 mcode = *((u4 *) (sp + 3 * 4));
420 um = (unresolved_method *) *((ptrint *) (sp + 2 * 4));
421 disp = *((s4 *) (sp + 1 * 4));
422 pv = (u1 *) *((ptrint *) (sp + 0 * 4));
424 PATCHER_MONITORENTER;
426 /* get the fieldinfo */
428 if (!(m = resolve_method_eager(um))) {
434 /* patch back original code */
436 *((u4 *) ra) = mcode;
438 /* synchronize instruction cache */
440 md_icacheflush(ra, 4);
442 /* patch stubroutine */
444 *((ptrint *) (pv + disp)) = (ptrint) m->stubroutine;
446 /* synchronize data cache */
448 md_dcacheflush(pv + disp, SIZEOF_VOID_P);
450 PATCHER_MARK_PATCHED_MONITOREXIT;
456 /* patcher_invokevirtual *******************************************************
460 <patched call position>
461 81830000 lwz r12,0(r3)
462 81ac0088 lwz r13,136(r12)
466 *******************************************************************************/
468 bool patcher_invokevirtual(u1 *sp)
471 java_objectheader *o;
473 unresolved_method *um;
477 /* get stuff from the stack */
479 ra = (u1 *) *((ptrint *) (sp + 5 * 4));
480 o = (java_objectheader *) *((ptrint *) (sp + 4 * 4));
481 mcode = *((u4 *) (sp + 3 * 4));
482 um = (unresolved_method *) *((ptrint *) (sp + 2 * 4));
484 PATCHER_MONITORENTER;
486 /* get the fieldinfo */
488 if (!(m = resolve_method_eager(um))) {
494 /* patch back original code */
496 *((u4 *) ra) = mcode;
498 /* if we show disassembly, we have to skip the nop */
500 if (opt_showdisassemble)
503 /* patch vftbl index */
505 disp = (OFFSET(vftbl_t, table[0]) + sizeof(methodptr) * m->vftblindex);
507 *((s4 *) (ra + 4)) |= (disp & 0x0000ffff);
509 /* synchronize instruction cache */
511 md_icacheflush(ra, 2 * 4);
513 PATCHER_MARK_PATCHED_MONITOREXIT;
519 /* patcher_invokeinterface *****************************************************
523 <patched call position>
524 81830000 lwz r12,0(r3)
525 818cffd0 lwz r12,-48(r12)
526 81ac000c lwz r13,12(r12)
530 *******************************************************************************/
532 bool patcher_invokeinterface(u1 *sp)
535 java_objectheader *o;
537 unresolved_method *um;
541 /* get stuff from the stack */
543 ra = (u1 *) *((ptrint *) (sp + 5 * 4));
544 o = (java_objectheader *) *((ptrint *) (sp + 4 * 4));
545 mcode = *((u4 *) (sp + 3 * 4));
546 um = (unresolved_method *) *((ptrint *) (sp + 2 * 4));
548 PATCHER_MONITORENTER;
550 /* get the fieldinfo */
552 if (!(m = resolve_method_eager(um))) {
558 /* patch back original code */
560 *((u4 *) ra) = mcode;
562 /* if we show disassembly, we have to skip the nop */
564 if (opt_showdisassemble)
567 /* patch interfacetable index */
569 disp = (OFFSET(vftbl_t, interfacetable[0]) - sizeof(methodptr*) * m->class->index);
571 *((s4 *) (ra + 1 * 4)) |= (disp & 0x0000ffff);
573 /* patch method offset */
575 disp = (sizeof(methodptr) * (m - m->class->methods));
577 *((s4 *) (ra + 2 * 4)) |= (disp & 0x0000ffff);
579 /* synchronize instruction cache */
581 md_icacheflush(ra, 3 * 4);
583 PATCHER_MARK_PATCHED_MONITOREXIT;
589 /* patcher_checkcast_instanceof_flags ******************************************
593 <patched call position>
594 818dff7c lwz r12,-132(r13)
596 *******************************************************************************/
598 bool patcher_checkcast_instanceof_flags(u1 *sp)
601 java_objectheader *o;
603 constant_classref *cr;
608 /* get stuff from the stack */
610 ra = (u1 *) *((ptrint *) (sp + 5 * 4));
611 o = (java_objectheader *) *((ptrint *) (sp + 4 * 4));
612 mcode = *((u4 *) (sp + 3 * 4));
613 cr = (constant_classref *) *((ptrint *) (sp + 2 * 4));
614 disp = *((s4 *) (sp + 1 * 4));
615 pv = (u1 *) *((ptrint *) (sp + 0 * 4));
617 PATCHER_MONITORENTER;
619 /* get the fieldinfo */
621 if (!(c = resolve_classref_eager(cr))) {
627 /* patch back original code */
629 *((u4 *) ra) = mcode;
631 /* synchronize instruction cache */
633 md_icacheflush(ra, 4);
635 /* patch class flags */
637 *((s4 *) (pv + disp)) = (s4) c->flags;
639 /* synchronize data cache */
641 md_dcacheflush(pv + disp, SIZEOF_VOID_P);
643 PATCHER_MARK_PATCHED_MONITOREXIT;
649 /* patcher_checkcast_instanceof_interface **************************************
653 <patched call position>
654 81870000 lwz r12,0(r7)
655 800c0010 lwz r0,16(r12)
656 34000000 addic. r0,r0,0
657 408101fc ble- 0x3002e518
658 800c0000 lwz r0,0(r12)
660 *******************************************************************************/
662 bool patcher_checkcast_instanceof_interface(u1 *sp)
665 java_objectheader *o;
667 constant_classref *cr;
671 /* get stuff from the stack */
673 ra = (u1 *) *((ptrint *) (sp + 5 * 4));
674 o = (java_objectheader *) *((ptrint *) (sp + 4 * 4));
675 mcode = *((u4 *) (sp + 3 * 4));
676 cr = (constant_classref *) *((ptrint *) (sp + 2 * 4));
678 PATCHER_MONITORENTER;
680 /* get the fieldinfo */
682 if (!(c = resolve_classref_eager(cr))) {
688 /* patch back original code */
690 *((u4 *) ra) = mcode;
692 /* if we show disassembly, we have to skip the nop */
694 if (opt_showdisassemble)
697 /* patch super class index */
701 *((s4 *) (ra + 2 * 4)) |= (disp & 0x0000ffff);
703 disp = (OFFSET(vftbl_t, interfacetable[0]) - c->index * sizeof(methodptr*);
705 *((s4 *) (ra + 4 * 4)) |= (disp & 0x0000ffff);
707 /* synchronize instruction cache */
709 md_icacheflush(ra, 5 * 4);
711 PATCHER_MARK_PATCHED_MONITOREXIT;
717 /* patcher_checkcast_class *****************************************************
721 <patched call position>
722 81870000 lwz r12,0(r7)
723 800c0014 lwz r0,20(r12)
724 818dff78 lwz r12,-136(r13)
726 *******************************************************************************/
728 bool patcher_checkcast_class(u1 *sp)
731 java_objectheader *o;
733 constant_classref *cr;
738 /* get stuff from the stack */
740 ra = (u1 *) *((ptrint *) (sp + 5 * 4));
741 o = (java_objectheader *) *((ptrint *) (sp + 4 * 4));
742 mcode = *((u4 *) (sp + 3 * 4));
743 cr = (constant_classref *) *((ptrint *) (sp + 2 * 4));
744 disp = *((s4 *) (sp + 1 * 4));
745 pv = (u1 *) *((ptrint *) (sp + 0 * 4));
747 PATCHER_MONITORENTER;
749 /* get the fieldinfo */
751 if (!(c = resolve_classref_eager(cr))) {
757 /* patch back original code */
759 *((u4 *) ra) = mcode;
761 /* synchronize instruction cache */
763 md_icacheflush(ra, 4);
765 /* patch super class' vftbl */
767 *((ptrint *) (pv + disp)) = (ptrint) c->vftbl;
769 /* synchronize data cache */
771 md_dcacheflush(pv + disp, SIZEOF_VOID_P);
773 PATCHER_MARK_PATCHED_MONITOREXIT;
779 /* patcher_instanceof_class ****************************************************
783 <patched call position>
784 817d0000 lwz r11,0(r29)
785 818dff8c lwz r12,-116(r13)
787 *******************************************************************************/
789 bool patcher_instanceof_class(u1 *sp)
792 java_objectheader *o;
794 constant_classref *cr;
799 /* get stuff from the stack */
801 ra = (u1 *) *((ptrint *) (sp + 5 * 4));
802 o = (java_objectheader *) *((ptrint *) (sp + 4 * 4));
803 mcode = *((u4 *) (sp + 3 * 4));
804 cr = (constant_classref *) *((ptrint *) (sp + 2 * 4));
805 disp = *((s4 *) (sp + 1 * 4));
806 pv = (u1 *) *((ptrint *) (sp + 0 * 4));
808 PATCHER_MONITORENTER;
810 /* get the fieldinfo */
812 if (!(c = resolve_classref_eager(cr))) {
818 /* patch back original code */
820 *((u4 *) ra) = mcode;
822 /* synchronize instruction cache */
824 md_icacheflush(ra, 4);
826 /* patch super class' vftbl */
828 *((ptrint *) (pv + disp)) = (ptrint) c->vftbl;
830 /* synchronize data cache */
832 md_dcacheflush(pv + disp, SIZEOF_VOID_P);
834 PATCHER_MARK_PATCHED_MONITOREXIT;
840 /* patcher_clinit **************************************************************
844 *******************************************************************************/
846 bool patcher_clinit(u1 *sp)
849 java_objectheader *o;
853 /* get stuff from the stack */
855 ra = (u1 *) *((ptrint *) (sp + 5 * 4));
856 o = (java_objectheader *) *((ptrint *) (sp + 4 * 4));
857 mcode = *((u4 *) (sp + 3 * 4));
858 c = (classinfo *) *((ptrint *) (sp + 2 * 4));
860 PATCHER_MONITORENTER;
862 /* check if the class is initialized */
864 if (!(c->state & CLASS_INITIALIZED)) {
865 if (!initialize_class(c)) {
872 /* patch back original code */
874 *((u4 *) ra) = mcode;
876 /* synchronize instruction cache */
878 md_icacheflush(ra, 4);
880 PATCHER_MARK_PATCHED_MONITOREXIT;
886 /* patcher_athrow_areturn ******************************************************
890 <patched call position>
892 *******************************************************************************/
894 #ifdef ENABLE_VERIFIER
895 bool patcher_athrow_areturn(u1 *sp)
898 java_objectheader *o;
900 unresolved_class *uc;
903 /* get stuff from the stack */
905 ra = (u1 *) *((ptrint *) (sp + 5 * 4));
906 o = (java_objectheader *) *((ptrint *) (sp + 4 * 4));
907 mcode = *((u4 *) (sp + 3 * 4));
908 uc = (unresolved_class *) *((ptrint *) (sp + 2 * 4));
910 PATCHER_MONITORENTER;
912 /* resolve the class */
914 if (!resolve_class(uc, resolveEager, false, &c)) {
920 /* patch back original code */
922 *((u4 *) ra) = mcode;
924 /* synchronize instruction cache */
926 md_icacheflush(ra, 4);
928 PATCHER_MARK_PATCHED_MONITOREXIT;
932 #endif /* ENABLE_VERIFIER */
935 /* patcher_resolve_native ******************************************************
939 *******************************************************************************/
941 #if !defined(WITH_STATIC_CLASSPATH)
942 bool patcher_resolve_native(u1 *sp)
945 java_objectheader *o;
952 /* get stuff from the stack */
954 ra = (u1 *) *((ptrint *) (sp + 5 * 4));
955 o = (java_objectheader *) *((ptrint *) (sp + 4 * 4));
956 mcode = *((u4 *) (sp + 3 * 4));
957 m = (methodinfo *) *((ptrint *) (sp + 2 * 4));
958 disp = *((s4 *) (sp + 1 * 4));
959 pv = (u1 *) *((ptrint *) (sp + 0 * 4));
961 /* calculate and set the new return address */
964 *((ptrint *) (sp + 5 * 4)) = (ptrint) ra;
966 PATCHER_MONITORENTER;
968 /* resolve native function */
970 if (!(f = native_resolve_function(m))) {
976 /* patch back original code */
978 *((u4 *) ra) = mcode;
980 /* synchronize instruction cache */
982 md_icacheflush(ra, 4);
984 /* patch native function pointer */
986 *((ptrint *) (pv + disp)) = (ptrint) f;
988 /* synchronize data cache */
990 md_dcacheflush(pv + disp, SIZEOF_VOID_P);
992 PATCHER_MARK_PATCHED_MONITOREXIT;
996 #endif /* !defined(WITH_STATIC_CLASSPATH) */
1000 * These are local overrides for various environment variables in Emacs.
1001 * Please do not remove this and leave it at the end of the file, where
1002 * Emacs will automagically detect them.
1003 * ---------------------------------------------------------------------
1006 * indent-tabs-mode: t
1010 * vim:noexpandtab:sw=4:ts=4: