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 7431 2007-03-01 13:49:14Z edwin $
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 <patched call position>
562 4c 8b 17 mov (%rdi),%r10
563 49 8b 82 00 00 00 00 mov 0x0(%r10),%rax
566 *******************************************************************************/
568 bool patcher_invokevirtual(u1 *sp)
573 unresolved_method *um;
576 /* get stuff from the stack */
578 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
579 mcode = *((u8 *) (sp + 3 * 8));
580 um = (unresolved_method *) *((ptrint *) (sp + 2 * 8));
582 /* get the fieldinfo */
584 if (!(m = resolve_method_eager(um)))
587 /* patch back original code */
589 *((u8 *) ra) = mcode;
591 /* if we show disassembly, we have to skip the nop's */
596 /* patch vftbl index */
598 *((s4 *) (ra + 3 + 3)) = (s4) (OFFSET(vftbl_t, table[0]) +
599 sizeof(methodptr) * m->vftblindex);
605 /* patcher_invokeinterface *****************************************************
609 <patched call position>
610 4c 8b 17 mov (%rdi),%r10
611 4d 8b 92 00 00 00 00 mov 0x0(%r10),%r10
612 49 8b 82 00 00 00 00 mov 0x0(%r10),%rax
615 *******************************************************************************/
617 bool patcher_invokeinterface(u1 *sp)
622 unresolved_method *um;
625 /* get stuff from the stack */
627 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
628 mcode = *((u8 *) (sp + 3 * 8));
629 um = (unresolved_method *) *((ptrint *) (sp + 2 * 8));
631 /* get the fieldinfo */
633 if (!(m = resolve_method_eager(um)))
636 /* patch back original code */
638 *((u8 *) ra) = mcode;
640 /* if we show disassembly, we have to skip the nop's */
645 /* patch interfacetable index */
647 *((s4 *) (ra + 3 + 3)) = (s4) (OFFSET(vftbl_t, interfacetable[0]) -
648 sizeof(methodptr) * m->class->index);
650 /* patch method offset */
652 *((s4 *) (ra + 3 + 7 + 3)) =
653 (s4) (sizeof(methodptr) * (m - m->class->methods));
659 /* patcher_resolve_classref_to_flags *******************************************
661 CHECKCAST/INSTANCEOF:
663 <patched call position>
665 *******************************************************************************/
667 __PORTED__ bool patcher_resolve_classref_to_flags(u1 *sp)
669 constant_classref *cr;
676 /* get stuff from the stack */
678 ra = (u1 *) *((ptrint *) (sp + 5 * 4));
679 mcode = *((u4 *) (sp + 3 * 4));
680 cr = (constant_classref *) *((ptrint *) (sp + 2 * 4));
681 disp = *((s4 *) (sp + 1 * 4));
682 pv = (u1 *) *((ptrint *) (sp + 0 * 4));
684 /* get the fieldinfo */
686 if (!(c = resolve_classref_eager(cr)))
689 /* patch class flags */
691 *((s4 *) (pv + disp)) = (s4) c->flags;
693 /* patch back original code */
695 *((u4 *) ra) = mcode;
700 /* patcher_resolve_classref_to_classinfo ***************************************
706 *******************************************************************************/
708 __PORTED__ bool patcher_resolve_classref_to_classinfo(u1 *sp)
710 constant_classref *cr;
717 /* get stuff from the stack */
719 ra = (u1 *) *((ptrint *) (sp + 5 * 4));
720 mcode = *((u4 *) (sp + 3 * 4));
721 cr = (constant_classref *) *((ptrint *) (sp + 2 * 4));
722 disp = *((s4 *) (sp + 1 * 4));
723 pv = (u1 *) *((ptrint *) (sp + 0 * 4));
725 /* get the classinfo */
727 if (!(c = resolve_classref_eager(cr)))
730 /* patch the classinfo pointer */
732 *((ptrint *) (pv + disp)) = (ptrint) c;
734 /* patch back original code */
736 *((u4 *) ra) = mcode;
741 /* patcher_resolve_classref_to_vftbl *******************************************
746 *******************************************************************************/
748 bool patcher_resolve_classref_to_vftbl(u1 *sp)
750 constant_classref *cr;
757 /* get stuff from the stack */
759 ra = (u1 *) *((ptrint *) (sp + 5 * 4));
760 mcode = *((u4 *) (sp + 3 * 4));
761 cr = (constant_classref *) *((ptrint *) (sp + 2 * 4));
762 disp = *((s4 *) (sp + 1 * 4));
763 pv = (u1 *) *((ptrint *) (sp + 0 * 4));
765 /* get the fieldinfo */
767 if (!(c = resolve_classref_eager(cr)))
770 /* patch super class' vftbl */
772 *((ptrint *) (pv + disp)) = (ptrint) c->vftbl;
774 /* patch back original code */
776 *((u4 *) ra) = mcode;
781 /* patcher_checkcast_instanceof_interface **************************************
785 <patched call position>
786 45 8b 9a 1c 00 00 00 mov 0x1c(%r10),%r11d
787 49 81 eb 00 00 00 00 sub $0x0,%r11
788 4d 85 db test %r11,%r11
789 0f 8e 94 04 00 00 jle 0x00002aaaaab018f8
790 4d 8b 9a 00 00 00 00 mov 0x0(%r10),%r11
792 *******************************************************************************/
794 bool patcher_checkcast_instanceof_interface(u1 *sp)
799 constant_classref *cr;
802 /* get stuff from the stack */
804 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
805 mcode = *((u8 *) (sp + 3 * 8));
806 cr = (constant_classref *) *((ptrint *) (sp + 2 * 8));
808 /* get the fieldinfo */
810 if (!(c = resolve_classref_eager(cr)))
813 /* patch back original code */
815 *((u8 *) ra) = mcode;
817 /* if we show disassembly, we have to skip the nop's */
822 /* patch super class index */
824 *((s4 *) (ra + 7 + 3)) = (s4) c->index;
826 *((s4 *) (ra + 7 + 7 + 3 + 6 + 3)) =
827 (s4) (OFFSET(vftbl_t, interfacetable[0]) -
828 c->index * sizeof(methodptr*));
834 /* patcher_checkcast_class *****************************************************
838 <patched call position>
839 49 bb 00 00 00 00 00 00 00 00 mov $0x0,%r11
840 45 8b 92 20 00 00 00 mov 0x20(%r10),%r10d
841 45 8b 9b 20 00 00 00 mov 0x20(%r11),%r11d
842 4d 29 da sub %r11,%r10
843 49 bb 00 00 00 00 00 00 00 00 mov $0x0,%r11
845 *******************************************************************************/
847 bool patcher_checkcast_class(u1 *sp)
852 constant_classref *cr;
855 /* get stuff from the stack */
857 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
858 mcode = *((u8 *) (sp + 3 * 8));
859 cr = (constant_classref *) *((ptrint *) (sp + 2 * 8));
861 /* get the fieldinfo */
863 if (!(c = resolve_classref_eager(cr)))
866 /* patch back original code */
868 *((u8 *) ra) = mcode;
870 /* if we show disassembly, we have to skip the nop's */
875 /* patch super class' vftbl */
877 *((ptrint *) (ra + 2)) = (ptrint) c->vftbl;
878 *((ptrint *) (ra + 10 + 7 + 7 + 3 + 2)) = (ptrint) c->vftbl;
884 /* patcher_instanceof_class ****************************************************
888 <patched call position>
889 49 ba 00 00 00 00 00 00 00 00 mov $0x0,%r10
891 *******************************************************************************/
893 bool patcher_instanceof_class(u1 *sp)
898 constant_classref *cr;
901 /* get stuff from the stack */
903 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
904 mcode = *((u8 *) (sp + 3 * 8));
905 cr = (constant_classref *) *((ptrint *) (sp + 2 * 8));
907 /* get the fieldinfo */
909 if (!(c = resolve_classref_eager(cr)))
912 /* patch back original code */
914 *((u8 *) ra) = mcode;
916 /* if we show disassembly, we have to skip the nop's */
921 /* patch super class' vftbl */
923 *((ptrint *) (ra + 2)) = (ptrint) c->vftbl;
929 /* patcher_clinit **************************************************************
931 May be used for GET/PUTSTATIC and in native stub.
935 *******************************************************************************/
937 __PORTED__ bool patcher_clinit(u1 *sp)
943 /* get stuff from the stack */
945 ra = (u1 *) *((ptrint *) (sp + 5 * 4));
946 mcode = *((u4 *) (sp + 3 * 4));
947 c = (classinfo *) *((ptrint *) (sp + 2 * 4));
949 /* check if the class is initialized */
951 if (!(c->state & CLASS_INITIALIZED))
952 if (!initialize_class(c))
955 /* patch back original code */
957 *((u4 *) ra) = mcode;
963 /* patcher_athrow_areturn ******************************************************
967 <patched call position>
969 *******************************************************************************/
971 #ifdef ENABLE_VERIFIER
972 __PORTED__ bool patcher_athrow_areturn(u1 *sp)
976 unresolved_class *uc;
978 /* get stuff from the stack */
980 ra = (u1 *) *((ptrint *) (sp + 5 * 4));
981 mcode = *((u4 *) (sp + 3 * 4));
982 uc = (unresolved_class *) *((ptrint *) (sp + 2 * 4));
984 /* resolve the class and check subtype constraints */
986 if (!resolve_class_eager_no_access_check(uc))
989 /* patch back original code */
991 *((u4 *) ra) = mcode;
995 #endif /* ENABLE_VERIFIER */
998 /* patcher_resolve_native ******************************************************
1000 *******************************************************************************/
1002 #if !defined(WITH_STATIC_CLASSPATH)
1003 __PORTED__ bool patcher_resolve_native(u1 *sp)
1012 /* get stuff from the stack */
1014 ra = (u1 *) *((ptrint *) (sp + 5 * 4));
1015 mcode = *((u4 *) (sp + 3 * 4));
1016 disp = *((s4 *) (sp + 1 * 4));
1017 m = (methodinfo *) *((ptrint *) (sp + 2 * 4));
1018 pv = (u1 *) *((ptrint *) (sp + 0 * 4));
1020 /* resolve native function */
1022 if (!(f = native_resolve_function(m)))
1025 /* patch native function pointer */
1027 *((ptrint *) (pv + disp)) = (ptrint) f;
1029 /* patch back original code */
1031 *((u4 *) ra) = mcode;
1035 #endif /* !defined(WITH_STATIC_CLASSPATH) */
1039 * These are local overrides for various environment variables in Emacs.
1040 * Please do not remove this and leave it at the end of the file, where
1041 * Emacs will automagically detect them.
1042 * ---------------------------------------------------------------------
1045 * indent-tabs-mode: t
1049 * vim:noexpandtab:sw=4:ts=4: