1 /* src/vm/jit/powerpc64/patcher.c - PowerPC64 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
25 $Id: patcher.c 7483 2007-03-08 13:17:40Z michi $
36 #include "mm/memory.h"
37 #include "native/native.h"
39 #include "vm/builtin.h"
40 #include "vm/exceptions.h"
41 #include "vm/initialize.h"
43 #include "vm/jit/asmpart.h"
44 #include "vm/jit/patcher.h"
45 #include "vm/jit/md.h"
46 #include "vm/jit/methodheader.h"
47 #include "vm/jit/stacktrace.h"
49 #include "vmcore/class.h"
50 #include "vmcore/field.h"
51 #include "vmcore/options.h"
52 #include "vmcore/references.h"
53 #include "vm/resolve.h"
56 /* patcher_wrapper *************************************************************
58 Wrapper for all patchers. It also creates the stackframe info
61 If the return value of the patcher function is false, it gets the
62 exception object, clears the exception pointer and returns the
65 *******************************************************************************/
67 java_objectheader *patcher_wrapper(u1 *sp, u1 *pv, u1 *ra)
76 /* define the patcher function */
78 bool (*patcher_function)(u1 *);
82 /* get stuff from the stack */
84 xpc = (u1 *) *((ptrint *) (sp + 5 * 8));
85 o = (java_objectheader *) *((ptrint *) (sp + 4 * 8));
86 f = (functionptr) *((ptrint *) (sp + 0 * 8));
88 /* store PV into the patcher function position */
90 *((ptrint *) (sp + 0 * 8)) = (ptrint) pv;
92 /* cast the passed function to a patcher function */
94 patcher_function = (bool (*)(u1 *)) (ptrint) f;
96 /* enter a monitor on the patching position */
100 /* create the stackframeinfo */
102 stacktrace_create_extern_stackframeinfo(&sfi, pv, sp + 8 * 8, ra, xpc);
104 /* call the proper patcher function */
106 result = (patcher_function)(sp);
108 /* remove the stackframeinfo */
110 stacktrace_remove_stackframeinfo(&sfi);
112 /* check for return value and exit accordingly */
114 if (result == false) {
115 e = exceptions_get_and_clear_exception();
122 PATCHER_MARK_PATCHED_MONITOREXIT;
128 /* patcher_get_putstatic *******************************************************
132 <patched call position>
133 816dffc8 lwz r11,-56(r13)
134 80ab0000 lwz r5,0(r11)
136 *******************************************************************************/
138 bool patcher_get_putstatic(u1 *sp)
142 unresolved_field *uf;
147 /* get stuff from the stack */
149 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
150 mcode = *((u4 *) (sp + 3 * 8));
151 uf = (unresolved_field *) *((ptrint *) (sp + 2 * 8));
152 disp = *((s4 *) (sp + 1 * 8));
153 pv = (u1 *) *((ptrint *) (sp + 0 * 8));
155 /* get the fieldinfo */
157 if (!(fi = resolve_field_eager(uf)))
160 /* check if the field's class is initialized */
162 if (!(fi->class->state & CLASS_INITIALIZED))
163 if (!initialize_class(fi->class))
166 /* patch back original code */
168 *((u4 *) ra) = mcode;
170 /* synchronize instruction cache */
172 md_icacheflush(ra, 4);
174 /* patch the field value's address */
176 *((ptrint *) (pv + disp)) = (ptrint) &(fi->value);
178 /* synchronize data cache */
180 md_dcacheflush(pv + disp, SIZEOF_VOID_P);
186 /* patcher_get_putfield ********************************************************
190 <patched call position>
191 811f0014 lwz r8,20(r31)
193 *******************************************************************************/
195 bool patcher_get_putfield(u1 *sp)
199 unresolved_field *uf;
203 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
204 mcode = *((u4 *) (sp + 3 * 8));
205 uf = (unresolved_field *) *((ptrint *) (sp + 2 * 8));
206 pv = (u1 *) *((ptrint *) (sp + 1 * 8));
208 /* get the fieldinfo */
210 if (!(fi = resolve_field_eager(uf)))
213 /* patch back original code */
215 *((u4 *) ra) = mcode;
217 /* if we show disassembly, we have to skip the nop */
219 if (opt_showdisassemble)
222 /* patch the field's offset */
224 *((u4 *) ra) |= (s2) (fi->offset & 0x0000ffff);
226 /* synchronize instruction cache */
228 md_icacheflush(ra, 8);
234 /* patcher_aconst **************************************************************
238 <patched call postition>
239 -------- ld r3,-64(r14)
240 -------- ld r14,-72(r14)
244 *******************************************************************************/
246 bool patcher_aconst(u1 *sp)
250 constant_classref *cr;
255 /* get stuff from the stack */
257 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
258 mcode = *((u4 *) (sp + 3 * 8));
259 cr = (constant_classref *) *((ptrint *) (sp + 2 * 8));
260 disp = *((s4 *) (sp + 1 * 8));
261 pv = (u1 *) *((ptrint *) (sp + 0 * 8));
263 /* get the classinfo */
265 if (!(c = resolve_classref_eager(cr)))
268 /* patch back original code */
270 *((u4 *) ra) = mcode;
272 /* synchronize instruction cache */
274 md_icacheflush(ra, 4);
276 /* patch the classinfo pointer */
278 *((ptrint *) (pv + disp)) = (ptrint) c;
280 /* synchronize data cache */
282 md_dcacheflush(pv + disp, SIZEOF_VOID_P);
288 /* patcher_builtin_multianewarray **********************************************
292 <patched call position>
293 808dffc0 lwz r4,-64(r13)
294 38a10038 addi r5,r1,56
295 81adffbc lwz r13,-68(r13)
299 *******************************************************************************/
301 bool patcher_builtin_multianewarray(u1 *sp)
305 constant_classref *cr;
310 /* get stuff from the stack */
312 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
313 mcode = *((u4 *) (sp + 3 * 8));
314 cr = (constant_classref *) *((ptrint *) (sp + 2 * 8));
315 disp = *((s4 *) (sp + 1 * 8));
316 pv = (u1 *) *((ptrint *) (sp + 0 * 8));
318 /* get the classinfo */
320 if (!(c = resolve_classref_eager(cr)))
323 /* patch back original code */
325 *((u4 *) ra) = mcode;
327 /* synchronize instruction cache */
329 md_icacheflush(ra, 4);
331 /* patch the classinfo pointer */
333 *((ptrint *) (pv + disp)) = (ptrint) c;
335 /* synchronize data cache */
337 md_dcacheflush(pv + disp, SIZEOF_VOID_P);
343 /* patcher_builtin_arraycheckcast **********************************************
347 <patched call position>
348 808dffd8 lwz r4,-40(r13)
349 81adffd4 lwz r13,-44(r13)
353 *******************************************************************************/
355 bool patcher_builtin_arraycheckcast(u1 *sp)
359 constant_classref *cr;
364 /* get stuff from the stack */
366 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
367 mcode = *((u4 *) (sp + 3 * 8));
368 cr = (constant_classref *) *((ptrint *) (sp + 2 * 8));
369 disp = *((s4 *) (sp + 1 * 8));
370 pv = (u1 *) *((ptrint *) (sp + 0 * 8));
372 /* get the classinfo */
374 if (!(c = resolve_classref_eager(cr)))
377 /* patch back original code */
379 *((u4 *) ra) = mcode;
381 /* synchronize instruction cache */
383 md_icacheflush(ra, 4);
385 /* patch the classinfo pointer */
387 *((ptrint *) (pv + disp)) = (ptrint) c;
389 /* synchronize data cache */
391 md_dcacheflush(pv + disp, SIZEOF_VOID_P);
397 /* patcher_invokestatic_special ************************************************
401 <patched call position>
402 81adffd8 lwz r13,-40(r13)
406 ******************************************************************************/
408 bool patcher_invokestatic_special(u1 *sp)
412 unresolved_method *um;
417 /* get stuff from the stack */
419 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
420 mcode = *((u4 *) (sp + 3 * 8));
421 um = (unresolved_method *) *((ptrint *) (sp + 2 * 8));
422 disp = *((s4 *) (sp + 1 * 8));
423 pv = (u1 *) *((ptrint *) (sp + 0 * 8));
425 /* get the fieldinfo */
427 if (!(m = resolve_method_eager(um)))
430 /* patch back original code */
432 *((u4 *) ra) = mcode;
434 /* synchronize instruction cache */
436 md_icacheflush(ra, 4);
438 /* patch stubroutine */
440 *((ptrint *) (pv + disp)) = (ptrint) m->stubroutine;
442 /* synchronize data cache */
444 md_dcacheflush(pv + disp, SIZEOF_VOID_P);
450 /* patcher_invokevirtual *******************************************************
454 <patched call position>
455 81830000 lwz r12,0(r3)
456 81ac0088 lwz r13,136(r12)
460 *******************************************************************************/
462 bool patcher_invokevirtual(u1 *sp)
466 unresolved_method *um;
470 /* get stuff from the stack */
472 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
473 mcode = *((u4 *) (sp + 3 * 8));
474 um = (unresolved_method *) *((ptrint *) (sp + 2 * 8));
476 /* get the fieldinfo */
478 if (!(m = resolve_method_eager(um)))
481 /* patch back original code */
483 *((u4 *) ra) = mcode;
485 /* if we show disassembly, we have to skip the nop */
487 if (opt_showdisassemble)
490 /* patch vftbl index */
492 disp = (OFFSET(vftbl_t, table[0]) + sizeof(methodptr) * m->vftblindex);
494 *((s4 *) (ra + 4)) |= (disp & 0x0000ffff);
496 /* synchronize instruction cache */
498 md_icacheflush(ra, 2 * 4);
504 /* patcher_invokeinterface *****************************************************
508 <patched call position>
509 81830000 lwz r12,0(r3)
510 818cffd0 lwz r12,-48(r12)
511 81ac000c lwz r13,12(r12)
515 *******************************************************************************/
517 bool patcher_invokeinterface(u1 *sp)
521 unresolved_method *um;
525 /* get stuff from the stack */
527 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
528 mcode = *((u4 *) (sp + 3 * 8));
529 um = (unresolved_method *) *((ptrint *) (sp + 2 * 8));
531 /* get the fieldinfo */
533 if (!(m = resolve_method_eager(um)))
536 /* patch back original code */
538 *((u4 *) ra) = mcode;
540 /* if we show disassembly, we have to skip the nop */
542 if (opt_showdisassemble)
545 /* patch interfacetable index */
547 disp = OFFSET(vftbl_t, interfacetable[0]) -
548 sizeof(methodptr*) * m->class->index;
550 /* XXX TWISTI: check displacement */
552 *((s4 *) (ra + 1 * 4)) |= (disp & 0x0000ffff);
554 /* patch method offset */
556 disp = sizeof(methodptr) * (m - m->class->methods);
558 /* XXX TWISTI: check displacement */
560 *((s4 *) (ra + 2 * 4)) |= (disp & 0x0000ffff);
562 /* synchronize instruction cache */
564 md_icacheflush(ra, 3 * 4);
570 /* patcher_checkcast_instanceof_flags ******************************************
574 <patched call position>
575 818dff7c lwz r12,-132(r13)
577 *******************************************************************************/
579 bool patcher_checkcast_instanceof_flags(u1 *sp)
583 constant_classref *cr;
588 /* get stuff from the stack */
590 ra = (u1 *) *((ptrint *) (sp + 5 * 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 /* get the fieldinfo */
598 if (!(c = resolve_classref_eager(cr)))
601 /* patch back original code */
603 *((u4 *) ra) = mcode;
605 /* synchronize instruction cache */
607 md_icacheflush(ra, 4);
609 /* patch class flags */
611 *((s4 *) (pv + disp)) = (s4) c->flags;
613 /* synchronize data cache */
615 md_dcacheflush(pv + disp, SIZEOF_VOID_P);
621 /* patcher_checkcast_instanceof_interface **************************************
625 <patched call position>
626 81870000 lwz r12,0(r7)
627 800c0010 lwz r0,16(r12)
628 34000000 addic. r0,r0,0
629 408101fc ble- 0x3002e518
630 800c0000 lwz r0,0(r12)
632 *******************************************************************************/
634 bool patcher_checkcast_instanceof_interface(u1 *sp)
638 constant_classref *cr;
642 /* get stuff from the stack */
644 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
645 mcode = *((u4 *) (sp + 3 * 8));
646 cr = (constant_classref *) *((ptrint *) (sp + 2 * 8));
648 /* get the fieldinfo */
650 if (!(c = resolve_classref_eager(cr)))
653 /* patch back original code */
655 *((u4 *) ra) = mcode;
657 /* if we show disassembly, we have to skip the nop */
659 if (opt_showdisassemble)
662 /* patch super class index */
666 *((s4 *) (ra + 2 * 4)) |= (disp & 0x0000ffff);
668 disp = OFFSET(vftbl_t, interfacetable[0]) - c->index * sizeof(methodptr*);
670 *((s4 *) (ra + 4 * 4)) |= (disp & 0x0000ffff);
672 /* synchronize instruction cache */
674 md_icacheflush(ra, 5 * 4);
680 /* patcher_checkcast_class *****************************************************
684 <patched call position>
685 81870000 lwz r12,0(r7)
686 800c0014 lwz r0,20(r12)
687 818dff78 lwz r12,-136(r13)
689 *******************************************************************************/
691 bool patcher_checkcast_class(u1 *sp)
695 constant_classref *cr;
700 /* get stuff from the stack */
702 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
703 mcode = *((u4 *) (sp + 3 * 8));
704 cr = (constant_classref *) *((ptrint *) (sp + 2 * 8));
705 disp = *((s4 *) (sp + 1 * 8));
706 pv = (u1 *) *((ptrint *) (sp + 0 * 8));
708 /* get the fieldinfo */
710 if (!(c = resolve_classref_eager(cr)))
713 /* patch back original code */
715 *((u4 *) ra) = mcode;
717 /* synchronize instruction cache */
719 md_icacheflush(ra, 4);
721 /* patch super class' vftbl */
723 *((ptrint *) (pv + disp)) = (ptrint) c->vftbl;
725 /* synchronize data cache */
727 md_dcacheflush(pv + disp, SIZEOF_VOID_P);
733 /* patcher_instanceof_class ****************************************************
737 <patched call position>
738 817d0000 lwz r11,0(r29)
739 818dff8c lwz r12,-116(r13)
741 *******************************************************************************/
743 bool patcher_instanceof_class(u1 *sp)
747 constant_classref *cr;
752 /* get stuff from the stack */
754 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
755 mcode = *((u4 *) (sp + 3 * 8));
756 cr = (constant_classref *) *((ptrint *) (sp + 2 * 8));
757 disp = *((s4 *) (sp + 1 * 8));
758 pv = (u1 *) *((ptrint *) (sp + 0 * 8));
760 /* get the fieldinfo */
762 if (!(c = resolve_classref_eager(cr)))
765 /* patch back original code */
767 *((u4 *) ra) = mcode;
769 /* synchronize instruction cache */
771 md_icacheflush(ra, 4);
773 /* patch super class' vftbl */
775 *((ptrint *) (pv + disp)) = (ptrint) c->vftbl;
777 /* synchronize data cache */
779 md_dcacheflush(pv + disp, SIZEOF_VOID_P);
785 /* patcher_clinit **************************************************************
789 *******************************************************************************/
791 bool patcher_clinit(u1 *sp)
797 /* get stuff from the stack */
799 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
800 mcode = *((u4 *) (sp + 3 * 8));
801 c = (classinfo *) *((ptrint *) (sp + 2 * 8));
803 /* check if the class is initialized */
805 if (!(c->state & CLASS_INITIALIZED))
806 if (!initialize_class(c))
809 /* patch back original code */
811 *((u4 *) ra) = mcode;
813 /* synchronize instruction cache */
815 md_icacheflush(ra, 4);
821 /* patcher_athrow_areturn ******************************************************
825 <patched call position>
827 *******************************************************************************/
829 #ifdef ENABLE_VERIFIER
830 bool patcher_athrow_areturn(u1 *sp)
834 unresolved_class *uc;
836 /* get stuff from the stack */
838 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
839 mcode = *((u4 *) (sp + 3 * 8));
840 uc = (unresolved_class *) *((ptrint *) (sp + 2 * 8));
842 /* resolve the class and check subtype constraints */
844 if (!resolve_class_eager_no_access_check(uc))
847 /* patch back original code */
849 *((u4 *) ra) = mcode;
851 /* synchronize instruction cache */
853 md_icacheflush(ra, 4);
857 #endif /* ENABLE_VERIFIER */
860 /* patcher_resolve_native ******************************************************
864 *******************************************************************************/
866 #if !defined(WITH_STATIC_CLASSPATH)
867 bool patcher_resolve_native(u1 *sp)
876 /* get stuff from the stack */
878 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
879 mcode = *((u4 *) (sp + 3 * 8));
880 m = (methodinfo *) *((ptrint *) (sp + 2 * 8));
881 disp = *((s4 *) (sp + 1 * 8));
882 pv = (u1 *) *((ptrint *) (sp + 0 * 8));
884 /* calculate and set the new return address */
887 *((ptrint *) (sp + 5 * 8)) = (ptrint) ra;
889 /* resolve native function */
891 if (!(f = native_resolve_function(m)))
894 /* patch back original code */
896 *((u4 *) ra) = mcode;
898 /* synchronize instruction cache */
900 md_icacheflush(ra, 4);
902 /* patch native function pointer */
904 *((ptrint *) (pv + disp)) = (ptrint) f;
906 /* synchronize data cache */
908 md_dcacheflush(pv + disp, SIZEOF_VOID_P);
912 #endif /* !defined(WITH_STATIC_CLASSPATH) */
916 * These are local overrides for various environment variables in Emacs.
917 * Please do not remove this and leave it at the end of the file, where
918 * Emacs will automagically detect them.
919 * ---------------------------------------------------------------------
922 * indent-tabs-mode: t
926 * vim:noexpandtab:sw=4:ts=4: