1 /* src/vm/jit/i386/patcher.c - i386 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 8143 2007-06-26 15:47:43Z twisti $
33 #include "vm/jit/i386/codegen.h"
35 #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/patcher.h"
44 #include "vm/jit/stacktrace.h"
46 #include "vmcore/class.h"
47 #include "vmcore/field.h"
48 #include "vmcore/options.h"
49 #include "vm/resolve.h"
50 #include "vmcore/references.h"
53 /* patcher_wrapper *************************************************************
55 Wrapper for all patchers. It also creates the stackframe info
58 If the return value of the patcher function is false, it gets the
59 exception object, clears the exception pointer and returns the
62 *******************************************************************************/
64 java_objectheader *patcher_wrapper(u1 *sp, u1 *pv, u1 *ra)
73 /* define the patcher function */
75 bool (*patcher_function)(u1 *);
77 /* get stuff from the stack */
79 xpc = (u1 *) *((ptrint *) (sp + 6 * 4));
80 o = (java_objectheader *) *((ptrint *) (sp + 4 * 4));
81 f = (functionptr) *((ptrint *) (sp + 0 * 4));
83 /* calculate and set the new return address */
85 xpc = xpc - PATCHER_CALL_SIZE;
87 *((ptrint *) (sp + 6 * 4)) = (ptrint) xpc;
89 /* cast the passed function to a patcher function */
91 patcher_function = (bool (*)(u1 *)) (ptrint) f;
93 /* enter a monitor on the patching position */
97 /* create the stackframeinfo */
99 /* RA is passed as NULL, but the XPC is correct and can be used in
100 stacktrace_create_extern_stackframeinfo for
101 md_codegen_get_pv_from_pc. */
103 stacktrace_create_extern_stackframeinfo(&sfi, pv, sp + 7 * 4, xpc, xpc);
105 /* call the proper patcher function */
107 result = (patcher_function)(sp);
109 /* remove the stackframeinfo */
111 stacktrace_remove_stackframeinfo(&sfi);
113 /* check for return value and exit accordingly */
115 if (result == false) {
116 e = exceptions_get_and_clear_exception();
123 PATCHER_MARK_PATCHED_MONITOREXIT;
129 /* patcher_get_putstatic *******************************************************
133 <patched call position>
134 b8 00 00 00 00 mov $0x00000000,%eax
136 *******************************************************************************/
138 bool patcher_get_putstatic(u1 *sp)
142 unresolved_field *uf;
145 /* get stuff from the stack */
147 ra = (u1 *) *((ptrint *) (sp + 6 * 4));
148 mcode = *((u8 *) (sp + 2 * 4));
149 uf = (unresolved_field *) *((ptrint *) (sp + 1 * 4));
151 /* get the fieldinfo */
153 if (!(fi = resolve_field_eager(uf)))
156 /* check if the field's class is initialized */
158 if (!(fi->class->state & CLASS_INITIALIZED))
159 if (!initialize_class(fi->class))
162 /* patch back original code */
164 *((u4 *) (ra + 0)) = (u4) mcode;
165 *((u1 *) (ra + 4)) = (u1) (mcode >> 32);
167 /* if we show disassembly, we have to skip the nop's */
172 /* patch the field value's address */
174 *((ptrint *) (ra + 1)) = (ptrint) &(fi->value);
180 /* patcher_getfield ************************************************************
184 <patched call position>
185 8b 88 00 00 00 00 mov 0x00000000(%eax),%ecx
187 *******************************************************************************/
189 bool patcher_getfield(u1 *sp)
193 unresolved_field *uf;
196 /* get stuff from the stack */
198 ra = (u1 *) *((ptrint *) (sp + 6 * 4));
199 mcode = *((u8 *) (sp + 2 * 4));
200 uf = (unresolved_field *) *((ptrint *) (sp + 1 * 4));
202 /* get the fieldinfo */
204 if (!(fi = resolve_field_eager(uf)))
207 /* patch back original code */
209 *((u4 *) (ra + 0)) = (u4) mcode;
210 *((u1 *) (ra + 4)) = (u1) (mcode >> 32);
212 /* if we show disassembly, we have to skip the nop's */
217 /* patch the field's offset */
219 *((u4 *) (ra + 2)) = (u4) (fi->offset);
221 /* if the field has type long, we need to patch the second move too */
223 if (fi->type == TYPE_LNG)
224 *((u4 *) (ra + 6 + 2)) = (u4) (fi->offset + 4);
230 /* patcher_putfield ************************************************************
234 <patched call position>
235 8b 88 00 00 00 00 mov 0x00000000(%eax),%ecx
237 *******************************************************************************/
239 bool patcher_putfield(u1 *sp)
243 unresolved_field *uf;
246 /* get stuff from the stack */
248 ra = (u1 *) *((ptrint *) (sp + 6 * 4));
249 mcode = *((u8 *) (sp + 2 * 4));
250 uf = (unresolved_field *) *((ptrint *) (sp + 1 * 4));
252 /* get the fieldinfo */
254 if (!(fi = resolve_field_eager(uf)))
257 /* patch back original code */
259 *((u4 *) (ra + 0)) = (u4) mcode;
260 *((u1 *) (ra + 4)) = (u1) (mcode >> 32);
262 /* if we show disassembly, we have to skip the nop's */
267 /* patch the field's offset */
269 if (fi->type != TYPE_LNG) {
270 *((u4 *) (ra + 2)) = (u4) (fi->offset);
273 /* The long code is special:
275 * 89 8d 00 00 00 00 mov %ecx,0x00000000(%ebp)
276 * 89 95 00 00 00 00 mov %edx,0x00000000(%ebp)
279 *((u4 *) (ra + 2)) = (u4) (fi->offset);
280 *((u4 *) (ra + 6 + 2)) = (u4) (fi->offset + 4);
287 /* patcher_putfieldconst *******************************************************
291 <patched call position>
292 c7 85 00 00 00 00 7b 00 00 00 movl $0x7b,0x0(%ebp)
294 *******************************************************************************/
296 bool patcher_putfieldconst(u1 *sp)
300 unresolved_field *uf;
303 /* get stuff from the stack */
305 ra = (u1 *) *((ptrint *) (sp + 6 * 4));
306 mcode = *((u8 *) (sp + 2 * 4));
307 uf = (unresolved_field *) *((ptrint *) (sp + 1 * 4));
309 /* get the fieldinfo */
311 if (!(fi = resolve_field_eager(uf)))
314 /* patch back original code */
316 *((u4 *) (ra + 0)) = (u4) mcode;
317 *((u1 *) (ra + 4)) = (u1) (mcode >> 32);
319 /* if we show disassembly, we have to skip the nop's */
324 /* patch the field's offset */
326 if (!IS_2_WORD_TYPE(fi->type)) {
327 *((u4 *) (ra + 2)) = (u4) (fi->offset);
330 /* long/double code is different:
332 * c7 80 00 00 00 00 c8 01 00 00 movl $0x1c8,0x0(%eax)
333 * c7 80 04 00 00 00 00 00 00 00 movl $0x0,0x4(%eax)
336 *((u4 *) (ra + 2)) = (u4) (fi->offset);
337 *((u4 *) (ra + 10 + 2)) = (u4) (fi->offset + 4);
344 /* patcher_aconst **************************************************************
348 <patched call postition>
349 c7 04 24 00 00 00 00 movl $0x0000000,(%esp)
350 b8 00 00 00 00 mov $0x0000000,%eax
352 *******************************************************************************/
354 bool patcher_aconst(u1 *sp)
358 constant_classref *cr;
361 /* get stuff from the stack */
363 ra = (u1 *) *((ptrint *) (sp + 6 * 4));
364 mcode = *((u8 *) (sp + 2 * 4));
365 cr = (constant_classref *) *((ptrint *) (sp + 1 * 4));
367 /* get the classinfo */
369 if (!(c = resolve_classref_eager(cr)))
372 /* patch back original code */
374 *((u4 *) (ra + 0)) = (u4) mcode;
375 *((u1 *) (ra + 4)) = (u1) (mcode >> 32);
377 /* if we show disassembly, we have to skip the nop's */
382 /* patch the classinfo pointer */
384 *((ptrint *) (ra + 1)) = (ptrint) c;
390 /* patcher_builtin_multianewarray **********************************************
394 <patched call position>
395 c7 04 24 02 00 00 00 movl $0x2,(%esp)
396 c7 44 24 04 00 00 00 00 movl $0x00000000,0x4(%esp)
398 83 c0 0c add $0xc,%eax
399 89 44 24 08 mov %eax,0x8(%esp)
400 b8 00 00 00 00 mov $0x00000000,%eax
403 *******************************************************************************/
405 bool patcher_builtin_multianewarray(u1 *sp)
409 constant_classref *cr;
412 /* get stuff from the stack */
414 ra = (u1 *) *((ptrint *) (sp + 6 * 4));
415 mcode = *((u8 *) (sp + 2 * 4));
416 cr = (constant_classref *) *((ptrint *) (sp + 1 * 4));
418 /* get the classinfo */
420 if (!(c = resolve_classref_eager(cr)))
423 /* patch back original code */
425 *((u4 *) (ra + 0)) = (u4) mcode;
426 *((u1 *) (ra + 4)) = (u1) (mcode >> 32);
428 /* if we show disassembly, we have to skip the nop's */
433 /* patch the classinfo pointer */
435 *((ptrint *) (ra + 7 + 4)) = (ptrint) c;
441 /* patcher_builtin_arraycheckcast **********************************************
445 <patched call position>
446 c7 44 24 04 00 00 00 00 movl $0x00000000,0x4(%esp)
447 ba 00 00 00 00 mov $0x00000000,%edx
450 *******************************************************************************/
452 bool patcher_builtin_arraycheckcast(u1 *sp)
456 constant_classref *cr;
459 /* get stuff from the stack */
461 ra = (u1 *) *((ptrint *) (sp + 6 * 4));
462 mcode = *((u8 *) (sp + 2 * 4));
463 cr = (constant_classref *) *((ptrint *) (sp + 1 * 4));
465 /* get the classinfo */
467 if (!(c = resolve_classref_eager(cr)))
470 /* patch back original code */
472 *((u4 *) (ra + 0)) = (u4) mcode;
473 *((u1 *) (ra + 4)) = (u1) (mcode >> 32);
475 /* if we show disassembly, we have to skip the nop's */
480 /* patch the classinfo pointer */
482 *((ptrint *) (ra + 4)) = (ptrint) c;
484 /* patch new function address */
486 *((ptrint *) (ra + 8 + 1)) = (ptrint) BUILTIN_arraycheckcast;
492 /* patcher_invokestatic_special ************************************************
496 <patched call position>
497 b9 00 00 00 00 mov $0x00000000,%ecx
500 *******************************************************************************/
502 bool patcher_invokestatic_special(u1 *sp)
506 unresolved_method *um;
509 /* get stuff from the stack */
511 ra = (u1 *) *((ptrint *) (sp + 6 * 4));
512 mcode = *((u8 *) (sp + 2 * 4));
513 um = (unresolved_method *) *((ptrint *) (sp + 1 * 4));
515 /* get the fieldinfo */
517 if (!(m = resolve_method_eager(um)))
520 /* patch back original code */
522 *((u4 *) (ra + 0)) = (u4) mcode;
523 *((u1 *) (ra + 4)) = (u1) (mcode >> 32);
525 /* if we show disassembly, we have to skip the nop's */
530 /* patch stubroutine */
532 *((ptrint *) (ra + 1)) = (ptrint) m->stubroutine;
538 /* patcher_invokevirtual *******************************************************
542 <patched call position>
543 8b 08 mov (%eax),%ecx
544 8b 81 00 00 00 00 mov 0x00000000(%ecx),%eax
547 *******************************************************************************/
549 bool patcher_invokevirtual(u1 *sp)
553 unresolved_method *um;
556 /* get stuff from the stack */
558 ra = (u1 *) *((ptrint *) (sp + 6 * 4));
559 mcode = *((u8 *) (sp + 2 * 4));
560 um = (unresolved_method *) *((ptrint *) (sp + 1 * 4));
562 /* get the fieldinfo */
564 if (!(m = resolve_method_eager(um)))
567 /* patch back original code */
569 *((u4 *) (ra + 0)) = (u4) mcode;
570 *((u1 *) (ra + 4)) = (u1) (mcode >> 32);
572 /* if we show disassembly, we have to skip the nop's */
577 /* patch vftbl index */
579 *((s4 *) (ra + 2 + 2)) = (s4) (OFFSET(vftbl_t, table[0]) +
580 sizeof(methodptr) * m->vftblindex);
586 /* patcher_invokeinterface *****************************************************
590 <patched call position>
591 8b 00 mov (%eax),%eax
592 8b 88 00 00 00 00 mov 0x00000000(%eax),%ecx
593 8b 81 00 00 00 00 mov 0x00000000(%ecx),%eax
596 *******************************************************************************/
598 bool patcher_invokeinterface(u1 *sp)
602 unresolved_method *um;
605 /* get stuff from the stack */
607 ra = (u1 *) *((ptrint *) (sp + 6 * 4));
608 mcode = *((u8 *) (sp + 2 * 4));
609 um = (unresolved_method *) *((ptrint *) (sp + 1 * 4));
611 /* get the fieldinfo */
613 if (!(m = resolve_method_eager(um)))
616 /* patch back original code */
618 *((u4 *) (ra + 0)) = (u4) mcode;
619 *((u1 *) (ra + 4)) = (u1) (mcode >> 32);
621 /* if we show disassembly, we have to skip the nop's */
626 /* patch interfacetable index */
628 *((s4 *) (ra + 2 + 2)) = (s4) (OFFSET(vftbl_t, interfacetable[0]) -
629 sizeof(methodptr) * m->class->index);
631 /* patch method offset */
633 *((s4 *) (ra + 2 + 6 + 2)) =
634 (s4) (sizeof(methodptr) * (m - m->class->methods));
640 /* patcher_checkcast_instanceof_flags ******************************************
644 <patched call position>
645 b9 00 00 00 00 mov $0x00000000,%ecx
647 *******************************************************************************/
649 bool patcher_checkcast_instanceof_flags(u1 *sp)
653 constant_classref *cr;
656 /* get stuff from the stack */
658 ra = (u1 *) *((ptrint *) (sp + 6 * 4));
659 mcode = *((u8 *) (sp + 2 * 4));
660 cr = (constant_classref *) *((ptrint *) (sp + 1 * 4));
662 /* get the fieldinfo */
664 if (!(c = resolve_classref_eager(cr)))
667 /* patch back original code */
669 *((u4 *) (ra + 0)) = (u4) mcode;
670 *((u1 *) (ra + 4)) = (u1) (mcode >> 32);
672 /* if we show disassembly, we have to skip the nop's */
677 /* patch class flags */
679 *((s4 *) (ra + 1)) = (s4) c->flags;
685 /* patcher_checkcast_interface *************************************************
689 <patched call position>
690 8b 91 00 00 00 00 mov 0x00000000(%ecx),%edx
691 81 ea 00 00 00 00 sub $0x00000000,%edx
693 0f 8f 06 00 00 00 jg 0x00000000
694 8b 35 03 00 00 00 mov 0x3,%esi
695 8b 91 00 00 00 00 mov 0x00000000(%ecx),%edx
697 *******************************************************************************/
699 bool patcher_checkcast_interface(u1 *sp)
703 constant_classref *cr;
706 /* get stuff from the stack */
708 ra = (u1 *) *((ptrint *) (sp + 6 * 4));
709 mcode = *((u8 *) (sp + 2 * 4));
710 cr = (constant_classref *) *((ptrint *) (sp + 1 * 4));
712 /* get the fieldinfo */
714 if (!(c = resolve_classref_eager(cr)))
717 /* patch back original code */
719 *((u4 *) (ra + 0)) = (u4) mcode;
720 *((u1 *) (ra + 4)) = (u1) (mcode >> 32);
722 /* if we show disassembly, we have to skip the nop's */
727 /* patch super class index */
729 *((s4 *) (ra + 6 + 2)) = (s4) c->index;
731 *((s4 *) (ra + 6 + 6 + 2 + 6 + 6 + 2)) =
732 (s4) (OFFSET(vftbl_t, interfacetable[0]) -
733 c->index * sizeof(methodptr*));
739 /* patcher_instanceof_interface ************************************************
743 <patched call position>
744 8b 91 00 00 00 00 mov 0x00000000(%ecx),%edx
745 81 ea 00 00 00 00 sub $0x00000000,%edx
747 0f 8e 13 00 00 00 jle 0x00000000
748 8b 91 00 00 00 00 mov 0x00000000(%ecx),%edx
750 *******************************************************************************/
752 bool patcher_instanceof_interface(u1 *sp)
756 constant_classref *cr;
759 /* get stuff from the stack */
761 ra = (u1 *) *((ptrint *) (sp + 6 * 4));
762 mcode = *((u8 *) (sp + 2 * 4));
763 cr = (constant_classref *) *((ptrint *) (sp + 1 * 4));
765 /* get the fieldinfo */
767 if (!(c = resolve_classref_eager(cr)))
770 /* patch back original code */
772 *((u4 *) (ra + 0)) = (u4) mcode;
773 *((u1 *) (ra + 4)) = (u1) (mcode >> 32);
775 /* if we show disassembly, we have to skip the nop's */
780 /* patch super class index */
782 *((s4 *) (ra + 6 + 2)) = (s4) c->index;
784 *((s4 *) (ra + 6 + 6 + 2 + 6 + 2)) =
785 (s4) (OFFSET(vftbl_t, interfacetable[0]) -
786 c->index * sizeof(methodptr*));
792 /* patcher_checkcast_class *****************************************************
796 <patched call position>
797 ba 00 00 00 00 mov $0x00000000,%edx
798 8b 89 00 00 00 00 mov 0x00000000(%ecx),%ecx
799 8b 92 00 00 00 00 mov 0x00000000(%edx),%edx
801 ba 00 00 00 00 mov $0x00000000,%edx
803 *******************************************************************************/
805 bool patcher_checkcast_class(u1 *sp)
809 constant_classref *cr;
812 /* get stuff from the stack */
814 ra = (u1 *) *((ptrint *) (sp + 6 * 4));
815 mcode = *((u8 *) (sp + 2 * 4));
816 cr = (constant_classref *) *((ptrint *) (sp + 1 * 4));
818 /* get the fieldinfo */
820 if (!(c = resolve_classref_eager(cr)))
823 /* patch back original code */
825 *((u4 *) (ra + 0)) = (u4) mcode;
826 *((u1 *) (ra + 4)) = (u1) (mcode >> 32);
828 /* if we show disassembly, we have to skip the nop's */
833 /* patch super class' vftbl */
835 *((ptrint *) (ra + 1)) = (ptrint) c->vftbl;
836 *((ptrint *) (ra + 5 + 6 + 6 + 2 + 1)) = (ptrint) c->vftbl;
842 /* patcher_instanceof_class ****************************************************
846 <patched call position>
847 b9 00 00 00 00 mov $0x0,%ecx
848 8b 40 14 mov 0x14(%eax),%eax
849 8b 51 18 mov 0x18(%ecx),%edx
850 8b 49 14 mov 0x14(%ecx),%ecx
852 *******************************************************************************/
854 bool patcher_instanceof_class(u1 *sp)
858 constant_classref *cr;
861 /* get stuff from the stack */
863 ra = (u1 *) *((ptrint *) (sp + 6 * 4));
864 mcode = *((u8 *) (sp + 2 * 4));
865 cr = (constant_classref *) *((ptrint *) (sp + 1 * 4));
867 /* get the fieldinfo */
869 if (!(c = resolve_classref_eager(cr)))
872 /* patch back original code */
874 *((u4 *) (ra + 0)) = (u4) mcode;
875 *((u1 *) (ra + 4)) = (u1) (mcode >> 32);
877 /* if we show disassembly, we have to skip the nop's */
882 /* patch super class' vftbl */
884 *((ptrint *) (ra + 1)) = (ptrint) c->vftbl;
890 /* patcher_clinit **************************************************************
892 Is used int PUT/GETSTATIC and native stub.
896 <patched call position>
898 *******************************************************************************/
900 bool patcher_clinit(u1 *sp)
906 /* get stuff from the stack */
908 ra = (u1 *) *((ptrint *) (sp + 6 * 4));
909 mcode = *((u8 *) (sp + 2 * 4));
910 c = (classinfo *) *((ptrint *) (sp + 1 * 4));
912 /* check if the class is initialized */
914 if (!(c->state & CLASS_INITIALIZED))
915 if (!initialize_class(c))
918 /* patch back original code */
920 *((u4 *) (ra + 0)) = (u4) mcode;
921 *((u1 *) (ra + 4)) = (u1) (mcode >> 32);
927 /* patcher_athrow_areturn ******************************************************
931 <patched call position>
933 *******************************************************************************/
935 #ifdef ENABLE_VERIFIER
936 bool patcher_athrow_areturn(u1 *sp)
940 unresolved_class *uc;
942 /* get stuff from the stack */
944 ra = (u1 *) *((ptrint *) (sp + 6 * 4));
945 mcode = *((u8 *) (sp + 2 * 4));
946 uc = (unresolved_class *) *((ptrint *) (sp + 1 * 4));
948 /* resolve the class and check subtype constraints */
950 if (!resolve_class_eager_no_access_check(uc))
953 /* patch back original code */
955 *((u4 *) (ra + 0)) = (u4) mcode;
956 *((u1 *) (ra + 4)) = (u1) (mcode >> 32);
960 #endif /* ENABLE_VERIFIER */
963 /* patcher_resolve_native ******************************************************
965 Is used in native stub.
969 <patched call position>
970 c7 44 24 04 28 90 01 40 movl $0x40019028,0x4(%esp)
972 *******************************************************************************/
974 #if !defined(WITH_STATIC_CLASSPATH)
975 bool patcher_resolve_native(u1 *sp)
982 /* get stuff from the stack */
984 ra = (u1 *) *((ptrint *) (sp + 6 * 4));
985 mcode = *((u8 *) (sp + 2 * 4));
986 m = (methodinfo *) *((ptrint *) (sp + 1 * 4));
988 /* resolve native function */
990 if (!(f = native_resolve_function(m)))
993 /* patch back original code */
995 *((u4 *) (ra + 0)) = (u4) mcode;
996 *((u1 *) (ra + 4)) = (u1) (mcode >> 32);
998 /* if we show disassembly, we have to skip the nop's */
1003 /* patch native function pointer */
1005 *((ptrint *) (ra + 4)) = (ptrint) f;
1009 #endif /* !defined(WITH_STATIC_CLASSPATH) */
1013 * These are local overrides for various environment variables in Emacs.
1014 * Please do not remove this and leave it at the end of the file, where
1015 * Emacs will automagically detect them.
1016 * ---------------------------------------------------------------------
1019 * indent-tabs-mode: t
1023 * vim:noexpandtab:sw=4:ts=4: