1 /* src/vm/jit/x86_64/patcher.c - x86_64 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 7442 2007-03-02 23:28:37Z pm $
39 #include "vm/jit/s390/codegen.h"
41 #include "mm/memory.h"
42 #include "native/native.h"
43 #include "vm/builtin.h"
44 #include "vmcore/class.h"
45 #include "vm/exceptions.h"
46 #include "vmcore/field.h"
47 #include "vm/initialize.h"
48 #include "vmcore/options.h"
49 #include "vmcore/references.h"
50 #include "vmcore/resolve.h"
51 #include "vm/jit/patcher.h"
52 #include "vm/jit/stacktrace.h"
55 #define OOPS() assert(0);
58 /* patcher_wrapper *************************************************************
60 Wrapper for all patchers. It also creates the stackframe info
63 If the return value of the patcher function is false, it gets the
64 exception object, clears the exception pointer and returns the
67 *******************************************************************************/
69 java_objectheader *patcher_wrapper(u1 *sp, u1 *pv, u1 *ra)
79 /* define the patcher function */
81 bool (*patcher_function)(u1 *);
83 /* get stuff from the stack */
85 xpc = (u1 *) *((ptrint *) (sp + 5 * 4));
86 o = (java_objectheader *) *((ptrint *) (sp + 4 * 4));
87 f = (functionptr) *((ptrint *) (sp + 0 * 4));
89 /* TODO here was PATCHER_CALL_SIZE previously ! */
90 xpc = xpc - 4; /* the patch position is 4 bytes before the RA */
92 *((ptrint *) (sp + 5 * 4)) = (ptrint) xpc;
94 /* store PV into the patcher function position */
96 *((ptrint *) (sp + 0 * 4)) = (ptrint) pv;
98 /* cast the passed function to a patcher function */
100 patcher_function = (bool (*)(u1 *)) (ptrint) f;
102 /* enter a monitor on the patching position */
104 PATCHER_MONITORENTER;
106 /* create the stackframeinfo */
108 /* RA is passed as NULL, but the XPC is correct and can be used in
109 stacktrace_create_extern_stackframeinfo for
110 md_codegen_get_pv_from_pc. */
112 stacktrace_create_extern_stackframeinfo(&sfi, pv, sp + (6 * 4), ra, xpc);
114 /* call the proper patcher function */
116 result = (patcher_function)(sp);
118 /* remove the stackframeinfo */
120 stacktrace_remove_stackframeinfo(&sfi);
122 /* check for return value and exit accordingly */
124 if (result == false) {
125 e = exceptions_get_and_clear_exception();
132 PATCHER_MARK_PATCHED_MONITOREXIT;
139 java_objectheader *o;
143 java_objectheader *e;
145 /* define the patcher function */
147 bool (*patcher_function)(u1 *);
151 /* get stuff from the stack */
153 xpc = (u1 *) *((ptrint *) (sp + 5 * 4));
154 o = (java_objectheader *) *((ptrint *) (sp + 4 * 4));
155 f = (functionptr) *((ptrint *) (sp + 0 * 4));
157 /* Correct RA is calculated in codegen.c and stored in the patcher
158 stub stack. There's no need to adjust xpc. */
160 /* store PV into the patcher function position */
162 *((ptrint *) (sp + 0 * 4)) = (ptrint) pv;
164 /* cast the passed function to a patcher function */
166 patcher_function = (bool (*)(u1 *)) (ptrint) f;
168 /* enter a monitor on the patching position */
170 PATCHER_MONITORENTER;
172 /* create the stackframeinfo */
174 stacktrace_create_extern_stackframeinfo(&sfi, pv, sp + 8 * 4, ra, xpc);
176 /* call the proper patcher function */
178 result = (patcher_function)(sp);
180 /* remove the stackframeinfo */
182 stacktrace_remove_stackframeinfo(&sfi);
184 /* check for return value and exit accordingly */
186 if (result == false) {
187 e = exceptions_get_and_clear_exception();
194 PATCHER_MARK_PATCHED_MONITOREXIT;
201 /* patcher_get_putstatic *******************************************************
205 *******************************************************************************/
207 bool patcher_get_putstatic(u1 *sp)
211 unresolved_field *uf;
216 /* get stuff from the stack */
218 ra = (u1 *) *((ptrint *) (sp + 5 * 4));
219 mcode = *((u4 *) (sp + 3 * 4));
220 uf = (unresolved_field *) *((ptrint *) (sp + 2 * 4));
221 disp = *((s4 *) (sp + 1 * 4));
222 pv = (u1 *) *((ptrint *) (sp + 0 * 4));
224 /* get the fieldinfo */
226 if (!(fi = resolve_field_eager(uf)))
229 /* check if the field's class is initialized */
231 if (!(fi->class->state & CLASS_INITIALIZED))
232 if (!initialize_class(fi->class))
235 *((ptrint *) (pv + disp)) = (ptrint) &(fi->value);
237 /* patch back original code */
239 *((u4 *) ra) = mcode;
245 /* patcher_get_putfield ********************************************************
249 <patched call position>
250 45 8b 8f 00 00 00 00 mov 0x0(%r15),%r9d
252 *******************************************************************************/
254 bool patcher_get_putfield(u1 *sp)
259 unresolved_field *uf;
263 /* get stuff from the stack */
265 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
266 mcode = *((u8 *) (sp + 3 * 8));
267 uf = (unresolved_field *) *((ptrint *) (sp + 2 * 8));
269 /* get the fieldinfo */
271 if (!(fi = resolve_field_eager(uf)))
274 /* patch back original code (instruction code is smaller than 8 bytes) */
276 *((u4 *) (ra + 0)) = (u4) mcode;
277 *((u1 *) (ra + 4)) = (u1) (mcode >> 32);
279 /* if we show disassembly, we have to skip the nop's */
284 /* patch the field's offset: we check for the field type, because the */
285 /* instructions have different lengths */
287 if (IS_INT_LNG_TYPE(fi->type)) {
288 /* check for special case: %rsp or %r12 as base register */
293 *((u4 *) (ra + 4)) = (u4) (fi->offset);
295 *((u4 *) (ra + 3)) = (u4) (fi->offset);
298 /* check for special case: %rsp or %r12 as base register */
303 *((u4 *) (ra + 6)) = (u4) (fi->offset);
305 *((u4 *) (ra + 5)) = (u4) (fi->offset);
312 /* patcher_putfieldconst *******************************************************
316 <patched call position>
317 41 c7 85 00 00 00 00 7b 00 00 00 movl $0x7b,0x0(%r13)
319 *******************************************************************************/
321 bool patcher_putfieldconst(u1 *sp)
326 unresolved_field *uf;
329 /* get stuff from the stack */
331 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
332 mcode = *((u8 *) (sp + 3 * 8));
333 uf = (unresolved_field *) *((ptrint *) (sp + 2 * 8));
335 /* get the fieldinfo */
337 if (!(fi = resolve_field_eager(uf)))
340 /* patch back original code */
342 *((u8 *) ra) = mcode;
344 /* if we show disassembly, we have to skip the nop's */
349 /* patch the field's offset */
351 if (IS_2_WORD_TYPE(fi->type) || IS_ADR_TYPE(fi->type)) {
352 /* handle special case when the base register is %r12 */
354 if (*(ra + 2) == 0x84) {
355 *((u4 *) (ra + 4)) = (u4) (fi->offset);
356 *((u4 *) (ra + 12 + 4)) = (u4) (fi->offset + 4);
359 *((u4 *) (ra + 3)) = (u4) (fi->offset);
360 *((u4 *) (ra + 11 + 3)) = (u4) (fi->offset + 4);
364 /* handle special case when the base register is %r12 */
366 if (*(ra + 2) == 0x84)
367 *((u4 *) (ra + 4)) = (u4) (fi->offset);
369 *((u4 *) (ra + 3)) = (u4) (fi->offset);
376 /* patcher_aconst **************************************************************
380 <patched call position>
381 48 bf a0 f0 92 00 00 00 00 00 mov $0x92f0a0,%rdi
383 *******************************************************************************/
385 bool patcher_aconst(u1 *sp)
390 constant_classref *cr;
393 /* get stuff from the stack */
395 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
396 mcode = *((u8 *) (sp + 3 * 8));
397 cr = (constant_classref *) *((ptrint *) (sp + 2 * 8));
399 /* get the classinfo */
401 if (!(c = resolve_classref_eager(cr)))
404 /* patch back original code */
406 *((u8 *) ra) = mcode;
408 /* if we show disassembly, we have to skip the nop's */
413 /* patch the classinfo pointer */
415 *((ptrint *) (ra + 2)) = (ptrint) c;
421 /* patcher_builtin_multianewarray **********************************************
425 <patched call position>
426 48 bf 02 00 00 00 00 00 00 00 mov $0x2,%rdi
427 48 be 30 40 b2 00 00 00 00 00 mov $0xb24030,%rsi
428 48 89 e2 mov %rsp,%rdx
429 48 b8 7c 96 4b 00 00 00 00 00 mov $0x4b967c,%rax
432 *******************************************************************************/
434 bool patcher_builtin_multianewarray(u1 *sp)
439 constant_classref *cr;
442 /* get stuff from the stack */
444 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
445 mcode = *((u8 *) (sp + 3 * 8));
446 cr = (constant_classref *) *((ptrint *) (sp + 2 * 8));
448 /* get the classinfo */
450 if (!(c = resolve_classref_eager(cr)))
453 /* patch back original code */
455 *((u8 *) ra) = mcode;
457 /* if we show disassembly, we have to skip the nop's */
462 /* patch the classinfo pointer */
464 *((ptrint *) (ra + 10 + 2)) = (ptrint) c;
470 /* patcher_builtin_arraycheckcast **********************************************
474 <patched call position>
475 48 be b8 3f b2 00 00 00 00 00 mov $0xb23fb8,%rsi
476 48 b8 00 00 00 00 00 00 00 00 mov $0x0,%rax
479 *******************************************************************************/
481 bool patcher_builtin_arraycheckcast(u1 *sp)
486 constant_classref *cr;
489 /* get stuff from the stack */
491 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
492 mcode = *((u8 *) (sp + 3 * 8));
493 cr = (constant_classref *) *((ptrint *) (sp + 2 * 8));
495 /* get the classinfo */
497 if (!(c = resolve_classref_eager(cr)))
500 /* patch back original code */
502 *((u8 *) ra) = mcode;
504 /* if we show disassembly, we have to skip the nop's */
509 /* patch the classinfo pointer */
511 *((ptrint *) (ra + 2)) = (ptrint) c;
517 /* patcher_invokestatic_special ************************************************
521 *******************************************************************************/
523 __PORTED__ bool patcher_invokestatic_special(u1 *sp)
527 unresolved_method *um;
532 /* get stuff from the stack */
534 ra = (u1 *) *((ptrint *) (sp + 5 * 4));
535 mcode = *((u4 *) (sp + 3 * 4));
536 um = (unresolved_method *) *((ptrint *) (sp + 2 * 4));
537 disp = *((s4 *) (sp + 1 * 4));
538 pv = (u1 *) *((ptrint *) (sp + 0 * 4));
540 /* get the fieldinfo */
542 if (!(m = resolve_method_eager(um)))
545 *((ptrint *) (pv + disp)) = (ptrint) m->stubroutine;
547 /* patch back original code */
549 *((u4 *) ra) = mcode;
551 /* patch stubroutine */
557 /* patcher_invokevirtual *******************************************************
561 *******************************************************************************/
563 bool patcher_invokevirtual(u1 *sp)
567 unresolved_method *um;
571 /* get stuff from the stack */
573 ra = (u1 *) *((ptrint *) (sp + 5 * 4));
574 mcode = *((u4 *) (sp + 3 * 4));
575 um = (unresolved_method *) *((ptrint *) (sp + 2 * 4));
577 /* get the fieldinfo */
579 if (!(m = resolve_method_eager(um)))
582 /* patch back original code */
584 *((u4 *) ra) = mcode;
586 /* patch vftbl index */
589 off = (s4) (OFFSET(vftbl_t, table[0]) +
590 sizeof(methodptr) * m->vftblindex);
592 assert((off >= 0) && (off <= 0xFFF));
594 *((s4 *)(ra + 4 + 4)) |= off;
600 /* patcher_invokeinterface *****************************************************
604 *******************************************************************************/
606 bool patcher_invokeinterface(u1 *sp)
610 unresolved_method *um;
614 /* get stuff from the stack */
616 ra = (u1 *) *((ptrint *) (sp + 5 * 4));
617 mcode = *((u4 *) (sp + 3 * 4));
618 um = (unresolved_method *) *((ptrint *) (sp + 2 * 4));
620 /* get the fieldinfo */
622 if (!(m = resolve_method_eager(um)))
625 /* patch back original code */
627 *((u4 *) ra) = mcode;
629 /* get interfacetable index */
631 idx = (s4) (OFFSET(vftbl_t, interfacetable[0]) -
632 sizeof(methodptr) * m->class->index) +
634 assert((idx >= 0) && (idx <= 0xFFF));
636 /* get method offset */
639 (s4) (sizeof(methodptr) * (m - m->class->methods));
640 assert((off >= 0) && (off <= 0xFFF));
644 *((s4 *)(ra + 4 + 4)) |= idx;
645 *((s4 *)(ra + 4 + 4 + 4)) |= off;
651 /* patcher_resolve_classref_to_flags *******************************************
653 CHECKCAST/INSTANCEOF:
655 <patched call position>
657 *******************************************************************************/
659 __PORTED__ bool patcher_resolve_classref_to_flags(u1 *sp)
661 constant_classref *cr;
668 /* get stuff from the stack */
670 ra = (u1 *) *((ptrint *) (sp + 5 * 4));
671 mcode = *((u4 *) (sp + 3 * 4));
672 cr = (constant_classref *) *((ptrint *) (sp + 2 * 4));
673 disp = *((s4 *) (sp + 1 * 4));
674 pv = (u1 *) *((ptrint *) (sp + 0 * 4));
676 /* get the fieldinfo */
678 if (!(c = resolve_classref_eager(cr)))
681 /* patch class flags */
683 *((s4 *) (pv + disp)) = (s4) c->flags;
685 /* patch back original code */
687 *((u4 *) ra) = mcode;
692 /* patcher_resolve_classref_to_classinfo ***************************************
698 *******************************************************************************/
700 __PORTED__ bool patcher_resolve_classref_to_classinfo(u1 *sp)
702 constant_classref *cr;
709 /* get stuff from the stack */
711 ra = (u1 *) *((ptrint *) (sp + 5 * 4));
712 mcode = *((u4 *) (sp + 3 * 4));
713 cr = (constant_classref *) *((ptrint *) (sp + 2 * 4));
714 disp = *((s4 *) (sp + 1 * 4));
715 pv = (u1 *) *((ptrint *) (sp + 0 * 4));
717 /* get the classinfo */
719 if (!(c = resolve_classref_eager(cr)))
722 /* patch the classinfo pointer */
724 *((ptrint *) (pv + disp)) = (ptrint) c;
726 /* patch back original code */
728 *((u4 *) ra) = mcode;
733 /* patcher_resolve_classref_to_vftbl *******************************************
738 *******************************************************************************/
740 bool patcher_resolve_classref_to_vftbl(u1 *sp)
742 constant_classref *cr;
749 /* get stuff from the stack */
751 ra = (u1 *) *((ptrint *) (sp + 5 * 4));
752 mcode = *((u4 *) (sp + 3 * 4));
753 cr = (constant_classref *) *((ptrint *) (sp + 2 * 4));
754 disp = *((s4 *) (sp + 1 * 4));
755 pv = (u1 *) *((ptrint *) (sp + 0 * 4));
757 /* get the fieldinfo */
759 if (!(c = resolve_classref_eager(cr)))
762 /* patch super class' vftbl */
764 *((ptrint *) (pv + disp)) = (ptrint) c->vftbl;
766 /* patch back original code */
768 *((u4 *) ra) = mcode;
773 /* patcher_checkcast_instanceof_interface **************************************
777 <patched call position>
778 45 8b 9a 1c 00 00 00 mov 0x1c(%r10),%r11d
779 49 81 eb 00 00 00 00 sub $0x0,%r11
780 4d 85 db test %r11,%r11
781 0f 8e 94 04 00 00 jle 0x00002aaaaab018f8
782 4d 8b 9a 00 00 00 00 mov 0x0(%r10),%r11
784 *******************************************************************************/
786 bool patcher_checkcast_instanceof_interface(u1 *sp)
791 constant_classref *cr;
794 /* get stuff from the stack */
796 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
797 mcode = *((u8 *) (sp + 3 * 8));
798 cr = (constant_classref *) *((ptrint *) (sp + 2 * 8));
800 /* get the fieldinfo */
802 if (!(c = resolve_classref_eager(cr)))
805 /* patch back original code */
807 *((u8 *) ra) = mcode;
809 /* if we show disassembly, we have to skip the nop's */
814 /* patch super class index */
816 *((s4 *) (ra + 7 + 3)) = (s4) c->index;
818 *((s4 *) (ra + 7 + 7 + 3 + 6 + 3)) =
819 (s4) (OFFSET(vftbl_t, interfacetable[0]) -
820 c->index * sizeof(methodptr*));
826 /* patcher_checkcast_class *****************************************************
830 <patched call position>
831 49 bb 00 00 00 00 00 00 00 00 mov $0x0,%r11
832 45 8b 92 20 00 00 00 mov 0x20(%r10),%r10d
833 45 8b 9b 20 00 00 00 mov 0x20(%r11),%r11d
834 4d 29 da sub %r11,%r10
835 49 bb 00 00 00 00 00 00 00 00 mov $0x0,%r11
837 *******************************************************************************/
839 bool patcher_checkcast_class(u1 *sp)
844 constant_classref *cr;
847 /* get stuff from the stack */
849 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
850 mcode = *((u8 *) (sp + 3 * 8));
851 cr = (constant_classref *) *((ptrint *) (sp + 2 * 8));
853 /* get the fieldinfo */
855 if (!(c = resolve_classref_eager(cr)))
858 /* patch back original code */
860 *((u8 *) ra) = mcode;
862 /* if we show disassembly, we have to skip the nop's */
867 /* patch super class' vftbl */
869 *((ptrint *) (ra + 2)) = (ptrint) c->vftbl;
870 *((ptrint *) (ra + 10 + 7 + 7 + 3 + 2)) = (ptrint) c->vftbl;
876 /* patcher_instanceof_class ****************************************************
880 <patched call position>
881 49 ba 00 00 00 00 00 00 00 00 mov $0x0,%r10
883 *******************************************************************************/
885 bool patcher_instanceof_class(u1 *sp)
890 constant_classref *cr;
893 /* get stuff from the stack */
895 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
896 mcode = *((u8 *) (sp + 3 * 8));
897 cr = (constant_classref *) *((ptrint *) (sp + 2 * 8));
899 /* get the fieldinfo */
901 if (!(c = resolve_classref_eager(cr)))
904 /* patch back original code */
906 *((u8 *) ra) = mcode;
908 /* if we show disassembly, we have to skip the nop's */
913 /* patch super class' vftbl */
915 *((ptrint *) (ra + 2)) = (ptrint) c->vftbl;
921 /* patcher_clinit **************************************************************
923 May be used for GET/PUTSTATIC and in native stub.
927 *******************************************************************************/
929 __PORTED__ bool patcher_clinit(u1 *sp)
935 /* get stuff from the stack */
937 ra = (u1 *) *((ptrint *) (sp + 5 * 4));
938 mcode = *((u4 *) (sp + 3 * 4));
939 c = (classinfo *) *((ptrint *) (sp + 2 * 4));
941 /* check if the class is initialized */
943 if (!(c->state & CLASS_INITIALIZED))
944 if (!initialize_class(c))
947 /* patch back original code */
949 *((u4 *) ra) = mcode;
955 /* patcher_athrow_areturn ******************************************************
959 <patched call position>
961 *******************************************************************************/
963 #ifdef ENABLE_VERIFIER
964 __PORTED__ bool patcher_athrow_areturn(u1 *sp)
968 unresolved_class *uc;
970 /* get stuff from the stack */
972 ra = (u1 *) *((ptrint *) (sp + 5 * 4));
973 mcode = *((u4 *) (sp + 3 * 4));
974 uc = (unresolved_class *) *((ptrint *) (sp + 2 * 4));
976 /* resolve the class and check subtype constraints */
978 if (!resolve_class_eager_no_access_check(uc))
981 /* patch back original code */
983 *((u4 *) ra) = mcode;
987 #endif /* ENABLE_VERIFIER */
990 /* patcher_resolve_native ******************************************************
992 *******************************************************************************/
994 #if !defined(WITH_STATIC_CLASSPATH)
995 __PORTED__ bool patcher_resolve_native(u1 *sp)
1004 /* get stuff from the stack */
1006 ra = (u1 *) *((ptrint *) (sp + 5 * 4));
1007 mcode = *((u4 *) (sp + 3 * 4));
1008 disp = *((s4 *) (sp + 1 * 4));
1009 m = (methodinfo *) *((ptrint *) (sp + 2 * 4));
1010 pv = (u1 *) *((ptrint *) (sp + 0 * 4));
1012 /* resolve native function */
1014 if (!(f = native_resolve_function(m)))
1017 /* patch native function pointer */
1019 *((ptrint *) (pv + disp)) = (ptrint) f;
1021 /* patch back original code */
1023 *((u4 *) ra) = mcode;
1027 #endif /* !defined(WITH_STATIC_CLASSPATH) */
1031 * These are local overrides for various environment variables in Emacs.
1032 * Please do not remove this and leave it at the end of the file, where
1033 * Emacs will automagically detect them.
1034 * ---------------------------------------------------------------------
1037 * indent-tabs-mode: t
1041 * vim:noexpandtab:sw=4:ts=4: