1 /* src/vm/jit/i386/patcher.c - i386 code patching functions
3 Copyright (C) 1996-2005 R. Grafl, A. Krall, C. Kruegel, C. Oates,
4 R. Obermaisser, M. Platter, M. Probst, S. Ring, E. Steiner,
5 C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich, J. Wenninger,
6 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., 59 Temple Place - Suite 330, Boston, MA
25 Contact: cacao@complang.tuwien.ac.at
27 Authors: Christian Thalinger
31 $Id: patcher.c 2773 2005-06-22 09:26:04Z twisti $
36 #include "vm/jit/i386/types.h"
38 #include "native/native.h"
39 #include "vm/builtin.h"
41 #include "vm/initialize.h"
42 #include "vm/options.h"
43 #include "vm/references.h"
44 #include "vm/jit/helper.h"
45 #include "vm/jit/patcher.h"
48 /* patcher_get_putstatic *******************************************************
52 <patched call position>
53 b8 00 00 00 00 mov $0x00000000,%eax
55 *******************************************************************************/
57 bool patcher_get_putstatic(u1 *sp)
65 /* get stuff from the stack */
67 ra = (u1 *) *((ptrint *) (sp + 4 * 4));
68 o = (java_objectheader *) *((ptrint *) (sp + 3 * 4));
69 mcode = *((u8 *) (sp + 1 * 4));
70 uf = (unresolved_field *) *((ptrint *) (sp + 0 * 4));
72 /* calculate and set the new return address */
75 *((ptrint *) (sp + 4 * 4)) = (ptrint) ra;
79 /* get the fieldinfo */
81 if (!(fi = helper_resolve_fieldinfo(uf))) {
87 /* check if the field's class is initialized */
89 if (!fi->class->initialized) {
90 if (!initialize_class(fi->class)) {
97 /* patch back original code */
99 *((u4 *) (ra + 0)) = (u4) mcode;
100 *((u1 *) (ra + 4)) = (u1) (mcode >> 32);
102 /* if we show disassembly, we have to skip the nop's */
107 /* patch the field value's address */
109 *((ptrint *) (ra + 1)) = (ptrint) &(fi->value);
111 PATCHER_MARK_PATCHED_MONITOREXIT;
117 /* patcher_getfield ************************************************************
121 <patched call position>
122 8b 88 00 00 00 00 mov 0x00000000(%eax),%ecx
124 *******************************************************************************/
126 bool patcher_getfield(u1 *sp)
129 java_objectheader *o;
131 unresolved_field *uf;
134 /* get stuff from the stack */
136 ra = (u1 *) *((ptrint *) (sp + 4 * 4));
137 o = (java_objectheader *) *((ptrint *) (sp + 3 * 4));
138 mcode = *((u8 *) (sp + 1 * 4));
139 uf = (unresolved_field *) *((ptrint *) (sp + 0 * 4));
141 /* calculate and set the new return address */
144 *((ptrint *) (sp + 4 * 4)) = (ptrint) ra;
146 PATCHER_MONITORENTER;
148 /* get the fieldinfo */
150 if (!(fi = helper_resolve_fieldinfo(uf))) {
156 /* patch back original code */
158 *((u4 *) (ra + 0)) = (u4) mcode;
159 *((u1 *) (ra + 4)) = (u1) (mcode >> 32);
161 /* if we show disassembly, we have to skip the nop's */
166 /* patch the field's offset */
168 *((u4 *) (ra + 2)) = (u4) (fi->offset);
170 /* if the field has type long, we need to patch the second move too */
172 if (fi->type == TYPE_LNG)
173 *((u4 *) (ra + 6 + 2)) = (u4) (fi->offset + 4);
175 PATCHER_MARK_PATCHED_MONITOREXIT;
181 /* patcher_putfield ************************************************************
185 <patched call position>
186 8b 88 00 00 00 00 mov 0x00000000(%eax),%ecx
188 *******************************************************************************/
190 bool patcher_putfield(u1 *sp)
193 java_objectheader *o;
195 unresolved_field *uf;
198 /* get stuff from the stack */
200 ra = (u1 *) *((ptrint *) (sp + 4 * 4));
201 o = (java_objectheader *) *((ptrint *) (sp + 3 * 4));
202 mcode = *((u8 *) (sp + 1 * 4));
203 uf = (unresolved_field *) *((ptrint *) (sp + 0 * 4));
205 /* calculate and set the new return address */
208 *((ptrint *) (sp + 4 * 4)) = (ptrint) ra;
210 PATCHER_MONITORENTER;
212 /* get the fieldinfo */
214 if (!(fi = helper_resolve_fieldinfo(uf))) {
220 /* patch back original code */
222 *((u4 *) (ra + 0)) = (u4) mcode;
223 *((u1 *) (ra + 4)) = (u1) (mcode >> 32);
225 /* if we show disassembly, we have to skip the nop's */
230 /* patch the field's offset */
232 if (fi->type != TYPE_LNG) {
233 *((u4 *) (ra + 2)) = (u4) (fi->offset);
236 /* long code is very special:
238 * 8b 8c 24 00 00 00 00 mov 0x00000000(%esp),%ecx
239 * 8b 94 24 00 00 00 00 mov 0x00000000(%esp),%edx
240 * 89 8d 00 00 00 00 mov %ecx,0x00000000(%ebp)
241 * 89 95 00 00 00 00 mov %edx,0x00000000(%ebp)
244 *((u4 *) (ra + 7 + 7 + 2)) = (u4) (fi->offset);
245 *((u4 *) (ra + 7 + 7 + 6 + 2)) = (u4) (fi->offset + 4);
248 PATCHER_MARK_PATCHED_MONITOREXIT;
254 /* patcher_putfieldconst *******************************************************
258 <patched call position>
259 c7 85 00 00 00 00 7b 00 00 00 movl $0x7b,0x0(%ebp)
261 *******************************************************************************/
263 bool patcher_putfieldconst(u1 *sp)
266 java_objectheader *o;
268 unresolved_field *uf;
271 /* get stuff from the stack */
273 ra = (u1 *) *((ptrint *) (sp + 4 * 4));
274 o = (java_objectheader *) *((ptrint *) (sp + 3 * 4));
275 mcode = *((u8 *) (sp + 1 * 4));
276 uf = (unresolved_field *) *((ptrint *) (sp + 0 * 4));
278 /* calculate and set the new return address */
281 *((ptrint *) (sp + 4 * 4)) = (ptrint) ra;
283 PATCHER_MONITORENTER;
285 /* get the fieldinfo */
287 if (!(fi = helper_resolve_fieldinfo(uf))) {
293 /* patch back original code */
295 *((u4 *) (ra + 0)) = (u4) mcode;
296 *((u1 *) (ra + 4)) = (u1) (mcode >> 32);
298 /* if we show disassembly, we have to skip the nop's */
303 /* patch the field's offset */
305 if (!IS_2_WORD_TYPE(fi->type)) {
306 *((u4 *) (ra + 2)) = (u4) (fi->offset);
309 /* long/double code is different:
311 * c7 80 00 00 00 00 c8 01 00 00 movl $0x1c8,0x0(%eax)
312 * c7 80 04 00 00 00 00 00 00 00 movl $0x0,0x4(%eax)
315 *((u4 *) (ra + 2)) = (u4) (fi->offset);
316 *((u4 *) (ra + 10 + 2)) = (u4) (fi->offset + 4);
319 PATCHER_MARK_PATCHED_MONITOREXIT;
325 /* patcher_builtin_new *********************************************************
329 c7 04 24 00 00 00 00 movl $0x0000000,(%esp)
330 <patched call postition>
331 b8 00 00 00 00 mov $0x0000000,%eax
334 *******************************************************************************/
336 bool patcher_builtin_new(u1 *sp)
339 java_objectheader *o;
341 constant_classref *cr;
344 /* get stuff from the stack */
346 ra = (u1 *) *((ptrint *) (sp + 4 * 4));
347 o = (java_objectheader *) *((ptrint *) (sp + 3 * 4));
348 mcode = *((u8 *) (sp + 1 * 4));
349 cr = (constant_classref *) *((ptrint *) (sp + 0 * 4));
351 /* calculate and set the new return address */
354 *((ptrint *) (sp + 4 * 4)) = (ptrint) ra;
356 PATCHER_MONITORENTER;
358 /* get the classinfo */
360 if (!(c = helper_resolve_classinfo(cr))) {
366 /* patch back original code */
368 *((u4 *) (ra + 7 + 0)) = (u4) mcode;
369 *((u1 *) (ra + 7 + 4)) = (u1) (mcode >> 32);
371 /* patch the classinfo pointer */
373 *((ptrint *) (ra + 3)) = (ptrint) c;
375 /* if we show disassembly, we have to skip the nop's */
380 /* patch new function address */
382 *((ptrint *) (ra + 7 + 1)) = (ptrint) BUILTIN_new;
384 PATCHER_MARK_PATCHED_MONITOREXIT;
390 /* patcher_builtin_newarray ****************************************************
394 c7 44 24 08 00 00 00 00 movl $0x00000000,0x8(%esp)
395 <patched call position>
396 b8 00 00 00 00 mov $0x00000000,%eax
399 *******************************************************************************/
401 bool patcher_builtin_newarray(u1 *sp)
404 java_objectheader *o;
406 constant_classref *cr;
409 /* get stuff from the stack */
411 ra = (u1 *) *((ptrint *) (sp + 4 * 4));
412 o = (java_objectheader *) *((ptrint *) (sp + 3 * 4));
413 mcode = *((u8 *) (sp + 1 * 4));
414 cr = (constant_classref *) *((ptrint *) (sp + 0 * 4));
416 /* calculate and set the new return address */
419 *((ptrint *) (sp + 4 * 4)) = (ptrint) ra;
421 PATCHER_MONITORENTER;
423 /* get the classinfo */
425 if (!(c = helper_resolve_classinfo(cr))) {
431 /* patch back original code */
433 *((u4 *) (ra + 8 + 0)) = (u4) mcode;
434 *((u1 *) (ra + 8 + 4)) = (u1) (mcode >> 32);
436 /* patch the class' vftbl pointer */
438 *((ptrint *) (ra + 4)) = (ptrint) c->vftbl;
440 /* if we show disassembly, we have to skip the nop's */
445 /* patch new function address */
447 *((ptrint *) (ra + 8 + 1)) = (ptrint) BUILTIN_newarray;
449 PATCHER_MARK_PATCHED_MONITOREXIT;
455 /* patcher_builtin_multianewarray **********************************************
459 <patched call position>
460 c7 04 24 02 00 00 00 movl $0x2,(%esp)
461 c7 44 24 04 00 00 00 00 movl $0x00000000,0x4(%esp)
463 83 c0 0c add $0xc,%eax
464 89 44 24 08 mov %eax,0x8(%esp)
465 b8 00 00 00 00 mov $0x00000000,%eax
468 *******************************************************************************/
470 bool patcher_builtin_multianewarray(u1 *sp)
473 java_objectheader *o;
475 constant_classref *cr;
478 /* get stuff from the stack */
480 ra = (u1 *) *((ptrint *) (sp + 4 * 4));
481 o = (java_objectheader *) *((ptrint *) (sp + 3 * 4));
482 mcode = *((u8 *) (sp + 1 * 4));
483 cr = (constant_classref *) *((ptrint *) (sp + 0 * 4));
485 /* calculate and set the new return address */
488 *((ptrint *) (sp + 4 * 4)) = (ptrint) ra;
490 PATCHER_MONITORENTER;
492 /* get the classinfo */
494 if (!(c = helper_resolve_classinfo(cr))) {
500 /* patch back original code */
502 *((u4 *) (ra + 0)) = (u4) mcode;
503 *((u1 *) (ra + 4)) = (u1) (mcode >> 32);
505 /* if we show disassembly, we have to skip the nop's */
510 /* patch the class' vftbl pointer */
512 *((ptrint *) (ra + 7 + 4)) = (ptrint) c->vftbl;
514 /* patch new function address */
516 *((ptrint *) (ra + 7 + 8 + 2 + 3 + 4 + 1)) = (ptrint) BUILTIN_multianewarray;
518 PATCHER_MARK_PATCHED_MONITOREXIT;
524 /* patcher_builtin_arraycheckcast **********************************************
528 c7 44 24 08 00 00 00 00 movl $0x00000000,0x8(%esp)
529 <patched call position>
530 b8 00 00 00 00 mov $0x00000000,%eax
533 *******************************************************************************/
535 bool patcher_builtin_arraycheckcast(u1 *sp)
538 java_objectheader *o;
540 constant_classref *cr;
543 /* get stuff from the stack */
545 ra = (u1 *) *((ptrint *) (sp + 4 * 4));
546 o = (java_objectheader *) *((ptrint *) (sp + 3 * 4));
547 mcode = *((u8 *) (sp + 1 * 4));
548 cr = (constant_classref *) *((ptrint *) (sp + 0 * 4));
550 /* calculate and set the new return address */
553 *((ptrint *) (sp + 4 * 4)) = (ptrint) ra;
555 PATCHER_MONITORENTER;
557 /* get the classinfo */
559 if (!(c = helper_resolve_classinfo(cr))) {
565 /* patch back original code */
567 *((u4 *) (ra + 8 + 0)) = (u4) mcode;
568 *((u1 *) (ra + 8 + 4)) = (u1) (mcode >> 32);
570 /* patch the class' vftbl pointer */
572 *((ptrint *) (ra + 4)) = (ptrint) c->vftbl;
574 /* if we show disassembly, we have to skip the nop's */
579 /* patch new function address */
581 *((ptrint *) (ra + 8 + 1)) = (ptrint) BUILTIN_arraycheckcast;
583 PATCHER_MARK_PATCHED_MONITOREXIT;
589 /* patcher_builtin_arrayinstanceof *********************************************
593 c7 44 24 08 00 00 00 00 movl $0x00000000,0x8(%esp)
594 <patched call position>
595 b8 00 00 00 00 mov $0x00000000,%eax
598 *******************************************************************************/
600 bool patcher_builtin_arrayinstanceof(u1 *sp)
603 java_objectheader *o;
605 constant_classref *cr;
608 /* get stuff from the stack */
610 ra = (u1 *) *((ptrint *) (sp + 4 * 4));
611 o = (java_objectheader *) *((ptrint *) (sp + 3 * 4));
612 mcode = *((u8 *) (sp + 1 * 4));
613 cr = (constant_classref *) *((ptrint *) (sp + 0 * 4));
615 /* calculate and set the new return address */
618 *((ptrint *) (sp + 4 * 4)) = (ptrint) ra;
620 PATCHER_MONITORENTER;
622 /* get the classinfo */
624 if (!(c = helper_resolve_classinfo(cr))) {
630 /* patch back original code */
632 *((u4 *) (ra + 8 + 0)) = (u4) mcode;
633 *((u1 *) (ra + 8 + 4)) = (u1) (mcode >> 32);
635 /* patch the class' vftbl pointer */
637 *((ptrint *) (ra + 4)) = (ptrint) c->vftbl;
639 /* if we show disassembly, we have to skip the nop's */
644 /* patch new function address */
646 *((ptrint *) (ra + 8 + 1)) = (ptrint) BUILTIN_arrayinstanceof;
648 PATCHER_MARK_PATCHED_MONITOREXIT;
654 /* patcher_invokestatic_special ************************************************
658 <patched call position>
659 b9 00 00 00 00 mov $0x00000000,%ecx
662 *******************************************************************************/
664 bool patcher_invokestatic_special(u1 *sp)
667 java_objectheader *o;
669 unresolved_method *um;
672 /* get stuff from the stack */
674 ra = (u1 *) *((ptrint *) (sp + 4 * 4));
675 o = (java_objectheader *) *((ptrint *) (sp + 3 * 4));
676 mcode = *((u8 *) (sp + 1 * 4));
677 um = (unresolved_method *) *((ptrint *) (sp + 0 * 4));
679 /* calculate and set the new return address */
682 *((ptrint *) (sp + 4 * 4)) = (ptrint) ra;
684 PATCHER_MONITORENTER;
686 /* get the fieldinfo */
688 if (!(m = helper_resolve_methodinfo(um))) {
694 /* patch back original code */
696 *((u4 *) (ra + 0)) = (u4) mcode;
697 *((u1 *) (ra + 4)) = (u1) (mcode >> 32);
699 /* if we show disassembly, we have to skip the nop's */
704 /* patch stubroutine */
706 *((ptrint *) (ra + 1)) = (ptrint) m->stubroutine;
708 PATCHER_MARK_PATCHED_MONITOREXIT;
714 /* patcher_invokevirtual *******************************************************
718 <patched call position>
719 8b 08 mov (%eax),%ecx
720 8b 81 00 00 00 00 mov 0x00000000(%ecx),%eax
723 *******************************************************************************/
725 bool patcher_invokevirtual(u1 *sp)
728 java_objectheader *o;
730 unresolved_method *um;
733 /* get stuff from the stack */
735 ra = (u1 *) *((ptrint *) (sp + 4 * 4));
736 o = (java_objectheader *) *((ptrint *) (sp + 3 * 4));
737 mcode = *((u8 *) (sp + 1 * 4));
738 um = (unresolved_method *) *((ptrint *) (sp + 0 * 4));
740 /* calculate and set the new return address */
743 *((ptrint *) (sp + 4 * 4)) = (ptrint) ra;
745 PATCHER_MONITORENTER;
747 /* get the fieldinfo */
749 if (!(m = helper_resolve_methodinfo(um))) {
755 /* patch back original code */
757 *((u4 *) (ra + 0)) = (u4) mcode;
758 *((u1 *) (ra + 4)) = (u1) (mcode >> 32);
760 /* if we show disassembly, we have to skip the nop's */
765 /* patch vftbl index */
767 *((s4 *) (ra + 2 + 2)) = (s4) (OFFSET(vftbl_t, table[0]) +
768 sizeof(methodptr) * m->vftblindex);
770 PATCHER_MARK_PATCHED_MONITOREXIT;
776 /* patcher_invokeinterface *****************************************************
780 <patched call position>
781 8b 00 mov (%eax),%eax
782 8b 88 00 00 00 00 mov 0x00000000(%eax),%ecx
783 8b 81 00 00 00 00 mov 0x00000000(%ecx),%eax
786 *******************************************************************************/
788 bool patcher_invokeinterface(u1 *sp)
791 java_objectheader *o;
793 unresolved_method *um;
796 /* get stuff from the stack */
798 ra = (u1 *) *((ptrint *) (sp + 4 * 4));
799 o = (java_objectheader *) *((ptrint *) (sp + 3 * 4));
800 mcode = *((u8 *) (sp + 1 * 4));
801 um = (unresolved_method *) *((ptrint *) (sp + 0 * 4));
803 /* calculate and set the new return address */
806 *((ptrint *) (sp + 4 * 4)) = (ptrint) ra;
808 PATCHER_MONITORENTER;
810 /* get the fieldinfo */
812 if (!(m = helper_resolve_methodinfo(um))) {
818 /* patch back original code */
820 *((u4 *) (ra + 0)) = (u4) mcode;
821 *((u1 *) (ra + 4)) = (u1) (mcode >> 32);
823 /* if we show disassembly, we have to skip the nop's */
828 /* patch interfacetable index */
830 *((s4 *) (ra + 2 + 2)) = (s4) (OFFSET(vftbl_t, interfacetable[0]) -
831 sizeof(methodptr) * m->class->index);
833 /* patch method offset */
835 *((s4 *) (ra + 2 + 6 + 2)) =
836 (s4) (sizeof(methodptr) * (m - m->class->methods));
838 PATCHER_MARK_PATCHED_MONITOREXIT;
844 /* patcher_checkcast_instanceof_flags ******************************************
848 <patched call position>
849 b9 00 00 00 00 mov $0x00000000,%ecx
851 *******************************************************************************/
853 bool patcher_checkcast_instanceof_flags(u1 *sp)
856 java_objectheader *o;
858 constant_classref *cr;
861 /* get stuff from the stack */
863 ra = (u1 *) *((ptrint *) (sp + 4 * 4));
864 o = (java_objectheader *) *((ptrint *) (sp + 3 * 4));
865 mcode = *((u8 *) (sp + 1 * 4));
866 cr = (constant_classref *) *((ptrint *) (sp + 0 * 4));
868 /* calculate and set the new return address */
871 *((ptrint *) (sp + 4 * 4)) = (ptrint) ra;
873 PATCHER_MONITORENTER;
875 /* get the fieldinfo */
877 if (!(c = helper_resolve_classinfo(cr))) {
883 /* patch back original code */
885 *((u4 *) (ra + 0)) = (u4) mcode;
886 *((u1 *) (ra + 4)) = (u1) (mcode >> 32);
888 /* if we show disassembly, we have to skip the nop's */
893 /* patch class flags */
895 *((s4 *) (ra + 1)) = (s4) c->flags;
897 PATCHER_MARK_PATCHED_MONITOREXIT;
903 /* patcher_checkcast_instanceof_interface **************************************
907 <patched call position>
908 8b 91 00 00 00 00 mov 0x00000000(%ecx),%edx
909 81 ea 00 00 00 00 sub $0x00000000,%edx
911 0f 8e 00 00 00 00 jle 0x00000000
912 8b 91 00 00 00 00 mov 0x00000000(%ecx),%edx
914 *******************************************************************************/
916 bool patcher_checkcast_instanceof_interface(u1 *sp)
919 java_objectheader *o;
921 constant_classref *cr;
924 /* get stuff from the stack */
926 ra = (u1 *) *((ptrint *) (sp + 4 * 4));
927 o = (java_objectheader *) *((ptrint *) (sp + 3 * 4));
928 mcode = *((u8 *) (sp + 1 * 4));
929 cr = (constant_classref *) *((ptrint *) (sp + 0 * 4));
931 /* calculate and set the new return address */
934 *((ptrint *) (sp + 4 * 4)) = (ptrint) ra;
936 PATCHER_MONITORENTER;
938 /* get the fieldinfo */
940 if (!(c = helper_resolve_classinfo(cr))) {
946 /* patch back original code */
948 *((u4 *) (ra + 0)) = (u4) mcode;
949 *((u1 *) (ra + 4)) = (u1) (mcode >> 32);
951 /* if we show disassembly, we have to skip the nop's */
956 /* patch super class index */
958 *((s4 *) (ra + 6 + 2)) = (s4) c->index;
960 *((s4 *) (ra + 6 + 6 + 2 + 6 + 2)) =
961 (s4) (OFFSET(vftbl_t, interfacetable[0]) -
962 c->index * sizeof(methodptr*));
964 PATCHER_MARK_PATCHED_MONITOREXIT;
970 /* patcher_checkcast_class *****************************************************
974 <patched call position>
975 ba 00 00 00 00 mov $0x00000000,%edx
976 8b 89 00 00 00 00 mov 0x00000000(%ecx),%ecx
977 8b 92 00 00 00 00 mov 0x00000000(%edx),%edx
979 ba 00 00 00 00 mov $0x00000000,%edx
981 *******************************************************************************/
983 bool patcher_checkcast_class(u1 *sp)
986 java_objectheader *o;
988 constant_classref *cr;
991 /* get stuff from the stack */
993 ra = (u1 *) *((ptrint *) (sp + 4 * 4));
994 o = (java_objectheader *) *((ptrint *) (sp + 3 * 4));
995 mcode = *((u8 *) (sp + 1 * 4));
996 cr = (constant_classref *) *((ptrint *) (sp + 0 * 4));
998 /* calculate and set the new return address */
1001 *((ptrint *) (sp + 4 * 4)) = (ptrint) ra;
1003 PATCHER_MONITORENTER;
1005 /* get the fieldinfo */
1007 if (!(c = helper_resolve_classinfo(cr))) {
1008 PATCHER_MONITOREXIT;
1013 /* patch back original code */
1015 *((u4 *) (ra + 0)) = (u4) mcode;
1016 *((u1 *) (ra + 4)) = (u1) (mcode >> 32);
1018 /* if we show disassembly, we have to skip the nop's */
1020 if (showdisassemble)
1023 /* patch super class' vftbl */
1025 *((ptrint *) (ra + 1)) = (ptrint) c->vftbl;
1026 *((ptrint *) (ra + 5 + 6 + 6 + 2 + 1)) = (ptrint) c->vftbl;
1028 PATCHER_MARK_PATCHED_MONITOREXIT;
1034 /* patcher_instanceof_class ****************************************************
1038 <patched call position>
1039 b9 00 00 00 00 mov $0x0,%ecx
1040 8b 40 14 mov 0x14(%eax),%eax
1041 8b 51 18 mov 0x18(%ecx),%edx
1042 8b 49 14 mov 0x14(%ecx),%ecx
1044 *******************************************************************************/
1046 bool patcher_instanceof_class(u1 *sp)
1049 java_objectheader *o;
1051 constant_classref *cr;
1054 /* get stuff from the stack */
1056 ra = (u1 *) *((ptrint *) (sp + 4 * 4));
1057 o = (java_objectheader *) *((ptrint *) (sp + 3 * 4));
1058 mcode = *((u8 *) (sp + 1 * 4));
1059 cr = (constant_classref *) *((ptrint *) (sp + 0 * 4));
1061 /* calculate and set the new return address */
1064 *((ptrint *) (sp + 4 * 4)) = (ptrint) ra;
1066 PATCHER_MONITORENTER;
1068 /* get the fieldinfo */
1070 if (!(c = helper_resolve_classinfo(cr))) {
1071 PATCHER_MONITOREXIT;
1076 /* patch back original code */
1078 *((u4 *) (ra + 0)) = (u4) mcode;
1079 *((u1 *) (ra + 4)) = (u1) (mcode >> 32);
1081 /* if we show disassembly, we have to skip the nop's */
1083 if (showdisassemble)
1086 /* patch super class' vftbl */
1088 *((ptrint *) (ra + 1)) = (ptrint) c->vftbl;
1090 PATCHER_MARK_PATCHED_MONITOREXIT;
1096 /* patcher_clinit **************************************************************
1098 Is used int PUT/GETSTATIC and native stub.
1102 <patched call position>
1104 *******************************************************************************/
1106 bool patcher_clinit(u1 *sp)
1109 java_objectheader *o;
1113 /* get stuff from the stack */
1115 ra = (u1 *) *((ptrint *) (sp + 4 * 4));
1116 o = (java_objectheader *) *((ptrint *) (sp + 3 * 4));
1117 mcode = *((u8 *) (sp + 1 * 4));
1118 c = (classinfo *) *((ptrint *) (sp + 0 * 4));
1120 /* calculate and set the new return address */
1123 *((ptrint *) (sp + 4 * 4)) = (ptrint) ra;
1125 PATCHER_MONITORENTER;
1127 /* check if the class is initialized */
1129 if (!c->initialized) {
1130 if (!initialize_class(c)) {
1131 PATCHER_MONITOREXIT;
1137 /* patch back original code */
1139 *((u4 *) (ra + 0)) = (u4) mcode;
1140 *((u1 *) (ra + 4)) = (u1) (mcode >> 32);
1142 PATCHER_MARK_PATCHED_MONITOREXIT;
1148 /* patcher_resolve_native ******************************************************
1150 Is used in native stub.
1154 <patched call position>
1155 b8 00 00 00 00 mov $0x0,%eax
1158 *******************************************************************************/
1160 bool patcher_resolve_native(u1 *sp)
1163 java_objectheader *o;
1168 /* get stuff from the stack */
1170 ra = (u1 *) *((ptrint *) (sp + 4 * 4));
1171 o = (java_objectheader *) *((ptrint *) (sp + 3 * 4));
1172 mcode = *((u8 *) (sp + 1 * 4));
1173 m = (methodinfo *) *((ptrint *) (sp + 0 * 4));
1175 /* calculate and set the new return address */
1178 *((ptrint *) (sp + 4 * 4)) = (ptrint) ra;
1180 PATCHER_MONITORENTER;
1182 /* resolve native function */
1184 if (!(f = native_resolve_function(m))) {
1185 PATCHER_MONITOREXIT;
1190 /* patch back original code */
1192 *((u4 *) (ra + 0)) = (u4) mcode;
1193 *((u1 *) (ra + 4)) = (u1) (mcode >> 32);
1195 /* if we show disassembly, we have to skip the nop's */
1197 if (showdisassemble)
1200 /* patch native function pointer */
1202 *((ptrint *) (ra + 1)) = (ptrint) f;
1204 PATCHER_MARK_PATCHED_MONITOREXIT;
1211 * These are local overrides for various environment variables in Emacs.
1212 * Please do not remove this and leave it at the end of the file, where
1213 * Emacs will automagically detect them.
1214 * ---------------------------------------------------------------------
1217 * indent-tabs-mode: t
1221 * vim:noexpandtab:sw=4:ts=4: