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 3392 2005-10-10 13:40:11Z twisti $
39 #include "mm/memory.h"
40 #include "native/native.h"
41 #include "vm/builtin.h"
43 #include "vm/initialize.h"
44 #include "vm/options.h"
45 #include "vm/references.h"
46 #include "vm/jit/helper.h"
47 #include "vm/jit/patcher.h"
50 /* patcher_get_putstatic *******************************************************
54 <patched call position>
55 b8 00 00 00 00 mov $0x00000000,%eax
57 *******************************************************************************/
59 bool patcher_get_putstatic(u1 *sp)
67 /* get stuff from the stack */
69 ra = (u1 *) *((ptrint *) (sp + 4 * 4));
70 o = (java_objectheader *) *((ptrint *) (sp + 3 * 4));
71 mcode = *((u8 *) (sp + 1 * 4));
72 uf = (unresolved_field *) *((ptrint *) (sp + 0 * 4));
74 /* calculate and set the new return address */
77 *((ptrint *) (sp + 4 * 4)) = (ptrint) ra;
81 /* get the fieldinfo */
83 if (!(fi = helper_resolve_fieldinfo(uf))) {
89 /* check if the field's class is initialized */
91 if (!fi->class->initialized) {
92 if (!initialize_class(fi->class)) {
99 /* patch back original code */
101 *((u4 *) (ra + 0)) = (u4) mcode;
102 *((u1 *) (ra + 4)) = (u1) (mcode >> 32);
104 /* if we show disassembly, we have to skip the nop's */
106 if (opt_showdisassemble)
109 /* patch the field value's address */
111 *((ptrint *) (ra + 1)) = (ptrint) &(fi->value);
113 PATCHER_MARK_PATCHED_MONITOREXIT;
119 /* patcher_getfield ************************************************************
123 <patched call position>
124 8b 88 00 00 00 00 mov 0x00000000(%eax),%ecx
126 *******************************************************************************/
128 bool patcher_getfield(u1 *sp)
131 java_objectheader *o;
133 unresolved_field *uf;
136 /* get stuff from the stack */
138 ra = (u1 *) *((ptrint *) (sp + 4 * 4));
139 o = (java_objectheader *) *((ptrint *) (sp + 3 * 4));
140 mcode = *((u8 *) (sp + 1 * 4));
141 uf = (unresolved_field *) *((ptrint *) (sp + 0 * 4));
143 /* calculate and set the new return address */
146 *((ptrint *) (sp + 4 * 4)) = (ptrint) ra;
148 PATCHER_MONITORENTER;
150 /* get the fieldinfo */
152 if (!(fi = helper_resolve_fieldinfo(uf))) {
158 /* patch back original code */
160 *((u4 *) (ra + 0)) = (u4) mcode;
161 *((u1 *) (ra + 4)) = (u1) (mcode >> 32);
163 /* if we show disassembly, we have to skip the nop's */
165 if (opt_showdisassemble)
168 /* patch the field's offset */
170 *((u4 *) (ra + 2)) = (u4) (fi->offset);
172 /* if the field has type long, we need to patch the second move too */
174 if (fi->type == TYPE_LNG)
175 *((u4 *) (ra + 6 + 2)) = (u4) (fi->offset + 4);
177 PATCHER_MARK_PATCHED_MONITOREXIT;
183 /* patcher_putfield ************************************************************
187 <patched call position>
188 8b 88 00 00 00 00 mov 0x00000000(%eax),%ecx
190 *******************************************************************************/
192 bool patcher_putfield(u1 *sp)
195 java_objectheader *o;
197 unresolved_field *uf;
200 /* get stuff from the stack */
202 ra = (u1 *) *((ptrint *) (sp + 4 * 4));
203 o = (java_objectheader *) *((ptrint *) (sp + 3 * 4));
204 mcode = *((u8 *) (sp + 1 * 4));
205 uf = (unresolved_field *) *((ptrint *) (sp + 0 * 4));
207 /* calculate and set the new return address */
210 *((ptrint *) (sp + 4 * 4)) = (ptrint) ra;
212 PATCHER_MONITORENTER;
214 /* get the fieldinfo */
216 if (!(fi = helper_resolve_fieldinfo(uf))) {
222 /* patch back original code */
224 *((u4 *) (ra + 0)) = (u4) mcode;
225 *((u1 *) (ra + 4)) = (u1) (mcode >> 32);
227 /* if we show disassembly, we have to skip the nop's */
229 if (opt_showdisassemble)
232 /* patch the field's offset */
234 if (fi->type != TYPE_LNG) {
235 *((u4 *) (ra + 2)) = (u4) (fi->offset);
238 /* long code is very special:
240 * 8b 8c 24 00 00 00 00 mov 0x00000000(%esp),%ecx
241 * 8b 94 24 00 00 00 00 mov 0x00000000(%esp),%edx
242 * 89 8d 00 00 00 00 mov %ecx,0x00000000(%ebp)
243 * 89 95 00 00 00 00 mov %edx,0x00000000(%ebp)
246 *((u4 *) (ra + 7 + 7 + 2)) = (u4) (fi->offset);
247 *((u4 *) (ra + 7 + 7 + 6 + 2)) = (u4) (fi->offset + 4);
250 PATCHER_MARK_PATCHED_MONITOREXIT;
256 /* patcher_putfieldconst *******************************************************
260 <patched call position>
261 c7 85 00 00 00 00 7b 00 00 00 movl $0x7b,0x0(%ebp)
263 *******************************************************************************/
265 bool patcher_putfieldconst(u1 *sp)
268 java_objectheader *o;
270 unresolved_field *uf;
273 /* get stuff from the stack */
275 ra = (u1 *) *((ptrint *) (sp + 4 * 4));
276 o = (java_objectheader *) *((ptrint *) (sp + 3 * 4));
277 mcode = *((u8 *) (sp + 1 * 4));
278 uf = (unresolved_field *) *((ptrint *) (sp + 0 * 4));
280 /* calculate and set the new return address */
283 *((ptrint *) (sp + 4 * 4)) = (ptrint) ra;
285 PATCHER_MONITORENTER;
287 /* get the fieldinfo */
289 if (!(fi = helper_resolve_fieldinfo(uf))) {
295 /* patch back original code */
297 *((u4 *) (ra + 0)) = (u4) mcode;
298 *((u1 *) (ra + 4)) = (u1) (mcode >> 32);
300 /* if we show disassembly, we have to skip the nop's */
302 if (opt_showdisassemble)
305 /* patch the field's offset */
307 if (!IS_2_WORD_TYPE(fi->type)) {
308 *((u4 *) (ra + 2)) = (u4) (fi->offset);
311 /* long/double code is different:
313 * c7 80 00 00 00 00 c8 01 00 00 movl $0x1c8,0x0(%eax)
314 * c7 80 04 00 00 00 00 00 00 00 movl $0x0,0x4(%eax)
317 *((u4 *) (ra + 2)) = (u4) (fi->offset);
318 *((u4 *) (ra + 10 + 2)) = (u4) (fi->offset + 4);
321 PATCHER_MARK_PATCHED_MONITOREXIT;
327 /* patcher_builtin_new *********************************************************
331 c7 04 24 00 00 00 00 movl $0x0000000,(%esp)
332 <patched call postition>
333 b8 00 00 00 00 mov $0x0000000,%eax
336 *******************************************************************************/
338 bool patcher_builtin_new(u1 *sp)
341 java_objectheader *o;
343 constant_classref *cr;
346 /* get stuff from the stack */
348 ra = (u1 *) *((ptrint *) (sp + 4 * 4));
349 o = (java_objectheader *) *((ptrint *) (sp + 3 * 4));
350 mcode = *((u8 *) (sp + 1 * 4));
351 cr = (constant_classref *) *((ptrint *) (sp + 0 * 4));
353 /* calculate and set the new return address */
356 *((ptrint *) (sp + 4 * 4)) = (ptrint) ra;
358 PATCHER_MONITORENTER;
360 /* get the classinfo */
362 if (!(c = helper_resolve_classinfo_nonabstract(cr))) {
368 /* patch back original code */
370 *((u4 *) (ra + 7 + 0)) = (u4) mcode;
371 *((u1 *) (ra + 7 + 4)) = (u1) (mcode >> 32);
373 /* patch the classinfo pointer */
375 *((ptrint *) (ra + 3)) = (ptrint) c;
377 /* if we show disassembly, we have to skip the nop's */
379 if (opt_showdisassemble)
382 /* patch new function address */
384 *((ptrint *) (ra + 7 + 1)) = (ptrint) BUILTIN_new;
386 PATCHER_MARK_PATCHED_MONITOREXIT;
392 /* patcher_builtin_newarray ****************************************************
396 c7 44 24 08 00 00 00 00 movl $0x00000000,0x8(%esp)
397 <patched call position>
398 b8 00 00 00 00 mov $0x00000000,%eax
401 *******************************************************************************/
403 bool patcher_builtin_newarray(u1 *sp)
406 java_objectheader *o;
408 constant_classref *cr;
411 /* get stuff from the stack */
413 ra = (u1 *) *((ptrint *) (sp + 4 * 4));
414 o = (java_objectheader *) *((ptrint *) (sp + 3 * 4));
415 mcode = *((u8 *) (sp + 1 * 4));
416 cr = (constant_classref *) *((ptrint *) (sp + 0 * 4));
418 /* calculate and set the new return address */
421 *((ptrint *) (sp + 4 * 4)) = (ptrint) ra;
423 PATCHER_MONITORENTER;
425 /* get the classinfo */
427 if (!(c = helper_resolve_classinfo(cr))) {
433 /* patch back original code */
435 *((u4 *) (ra + 8 + 0)) = (u4) mcode;
436 *((u1 *) (ra + 8 + 4)) = (u1) (mcode >> 32);
438 /* patch the class' vftbl pointer */
440 *((ptrint *) (ra + 4)) = (ptrint) c->vftbl;
442 /* if we show disassembly, we have to skip the nop's */
444 if (opt_showdisassemble)
447 /* patch new function address */
449 *((ptrint *) (ra + 8 + 1)) = (ptrint) BUILTIN_newarray;
451 PATCHER_MARK_PATCHED_MONITOREXIT;
457 /* patcher_builtin_multianewarray **********************************************
461 <patched call position>
462 c7 04 24 02 00 00 00 movl $0x2,(%esp)
463 c7 44 24 04 00 00 00 00 movl $0x00000000,0x4(%esp)
465 83 c0 0c add $0xc,%eax
466 89 44 24 08 mov %eax,0x8(%esp)
467 b8 00 00 00 00 mov $0x00000000,%eax
470 *******************************************************************************/
472 bool patcher_builtin_multianewarray(u1 *sp)
475 java_objectheader *o;
477 constant_classref *cr;
480 /* get stuff from the stack */
482 ra = (u1 *) *((ptrint *) (sp + 4 * 4));
483 o = (java_objectheader *) *((ptrint *) (sp + 3 * 4));
484 mcode = *((u8 *) (sp + 1 * 4));
485 cr = (constant_classref *) *((ptrint *) (sp + 0 * 4));
487 /* calculate and set the new return address */
490 *((ptrint *) (sp + 4 * 4)) = (ptrint) ra;
492 PATCHER_MONITORENTER;
494 /* get the classinfo */
496 if (!(c = helper_resolve_classinfo(cr))) {
502 /* patch back original code */
504 *((u4 *) (ra + 0)) = (u4) mcode;
505 *((u1 *) (ra + 4)) = (u1) (mcode >> 32);
507 /* if we show disassembly, we have to skip the nop's */
509 if (opt_showdisassemble)
512 /* patch the class' vftbl pointer */
514 *((ptrint *) (ra + 7 + 4)) = (ptrint) c->vftbl;
516 /* patch new function address */
518 *((ptrint *) (ra + 7 + 8 + 2 + 3 + 4 + 1)) = (ptrint) BUILTIN_multianewarray;
520 PATCHER_MARK_PATCHED_MONITOREXIT;
526 /* patcher_builtin_arraycheckcast **********************************************
530 <patched call position>
531 c7 44 24 04 00 00 00 00 movl $0x00000000,0x4(%esp)
532 ba 00 00 00 00 mov $0x00000000,%edx
535 *******************************************************************************/
537 bool patcher_builtin_arraycheckcast(u1 *sp)
540 java_objectheader *o;
542 constant_classref *cr;
545 /* get stuff from the stack */
547 ra = (u1 *) *((ptrint *) (sp + 4 * 4));
548 o = (java_objectheader *) *((ptrint *) (sp + 3 * 4));
549 mcode = *((u8 *) (sp + 1 * 4));
550 cr = (constant_classref *) *((ptrint *) (sp + 0 * 4));
552 /* calculate and set the new return address */
555 *((ptrint *) (sp + 4 * 4)) = (ptrint) ra;
557 PATCHER_MONITORENTER;
559 /* get the classinfo */
561 if (!(c = helper_resolve_classinfo(cr))) {
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 */
574 if (opt_showdisassemble)
577 /* patch the class' vftbl pointer */
579 *((ptrint *) (ra + 4)) = (ptrint) c->vftbl;
581 /* patch new function address */
583 *((ptrint *) (ra + 8 + 1)) = (ptrint) BUILTIN_arraycheckcast;
585 PATCHER_MARK_PATCHED_MONITOREXIT;
591 /* patcher_builtin_arrayinstanceof *********************************************
595 c7 44 24 08 00 00 00 00 movl $0x00000000,0x8(%esp)
596 <patched call position>
597 b8 00 00 00 00 mov $0x00000000,%eax
600 *******************************************************************************/
602 bool patcher_builtin_arrayinstanceof(u1 *sp)
605 java_objectheader *o;
607 constant_classref *cr;
610 /* get stuff from the stack */
612 ra = (u1 *) *((ptrint *) (sp + 4 * 4));
613 o = (java_objectheader *) *((ptrint *) (sp + 3 * 4));
614 mcode = *((u8 *) (sp + 1 * 4));
615 cr = (constant_classref *) *((ptrint *) (sp + 0 * 4));
617 /* calculate and set the new return address */
620 *((ptrint *) (sp + 4 * 4)) = (ptrint) ra;
622 PATCHER_MONITORENTER;
624 /* get the classinfo */
626 if (!(c = helper_resolve_classinfo(cr))) {
632 /* patch back original code */
634 *((u4 *) (ra + 8 + 0)) = (u4) mcode;
635 *((u1 *) (ra + 8 + 4)) = (u1) (mcode >> 32);
637 /* patch the class' vftbl pointer */
639 *((ptrint *) (ra + 4)) = (ptrint) c->vftbl;
641 /* if we show disassembly, we have to skip the nop's */
643 if (opt_showdisassemble)
646 /* patch new function address */
648 *((ptrint *) (ra + 8 + 1)) = (ptrint) BUILTIN_arrayinstanceof;
650 PATCHER_MARK_PATCHED_MONITOREXIT;
656 /* patcher_invokestatic_special ************************************************
660 <patched call position>
661 b9 00 00 00 00 mov $0x00000000,%ecx
664 *******************************************************************************/
666 bool patcher_invokestatic_special(u1 *sp)
669 java_objectheader *o;
671 unresolved_method *um;
674 /* get stuff from the stack */
676 ra = (u1 *) *((ptrint *) (sp + 4 * 4));
677 o = (java_objectheader *) *((ptrint *) (sp + 3 * 4));
678 mcode = *((u8 *) (sp + 1 * 4));
679 um = (unresolved_method *) *((ptrint *) (sp + 0 * 4));
681 /* calculate and set the new return address */
684 *((ptrint *) (sp + 4 * 4)) = (ptrint) ra;
686 PATCHER_MONITORENTER;
688 /* get the fieldinfo */
690 if (!(m = helper_resolve_methodinfo(um))) {
696 /* patch back original code */
698 *((u4 *) (ra + 0)) = (u4) mcode;
699 *((u1 *) (ra + 4)) = (u1) (mcode >> 32);
701 /* if we show disassembly, we have to skip the nop's */
703 if (opt_showdisassemble)
706 /* patch stubroutine */
708 *((ptrint *) (ra + 1)) = (ptrint) m->stubroutine;
710 PATCHER_MARK_PATCHED_MONITOREXIT;
716 /* patcher_invokevirtual *******************************************************
720 <patched call position>
721 8b 08 mov (%eax),%ecx
722 8b 81 00 00 00 00 mov 0x00000000(%ecx),%eax
725 *******************************************************************************/
727 bool patcher_invokevirtual(u1 *sp)
730 java_objectheader *o;
732 unresolved_method *um;
735 /* get stuff from the stack */
737 ra = (u1 *) *((ptrint *) (sp + 4 * 4));
738 o = (java_objectheader *) *((ptrint *) (sp + 3 * 4));
739 mcode = *((u8 *) (sp + 1 * 4));
740 um = (unresolved_method *) *((ptrint *) (sp + 0 * 4));
742 /* calculate and set the new return address */
745 *((ptrint *) (sp + 4 * 4)) = (ptrint) ra;
747 PATCHER_MONITORENTER;
749 /* get the fieldinfo */
751 if (!(m = helper_resolve_methodinfo(um))) {
757 /* patch back original code */
759 *((u4 *) (ra + 0)) = (u4) mcode;
760 *((u1 *) (ra + 4)) = (u1) (mcode >> 32);
762 /* if we show disassembly, we have to skip the nop's */
764 if (opt_showdisassemble)
767 /* patch vftbl index */
769 *((s4 *) (ra + 2 + 2)) = (s4) (OFFSET(vftbl_t, table[0]) +
770 sizeof(methodptr) * m->vftblindex);
772 PATCHER_MARK_PATCHED_MONITOREXIT;
778 /* patcher_invokeinterface *****************************************************
782 <patched call position>
783 8b 00 mov (%eax),%eax
784 8b 88 00 00 00 00 mov 0x00000000(%eax),%ecx
785 8b 81 00 00 00 00 mov 0x00000000(%ecx),%eax
788 *******************************************************************************/
790 bool patcher_invokeinterface(u1 *sp)
793 java_objectheader *o;
795 unresolved_method *um;
798 /* get stuff from the stack */
800 ra = (u1 *) *((ptrint *) (sp + 4 * 4));
801 o = (java_objectheader *) *((ptrint *) (sp + 3 * 4));
802 mcode = *((u8 *) (sp + 1 * 4));
803 um = (unresolved_method *) *((ptrint *) (sp + 0 * 4));
805 /* calculate and set the new return address */
808 *((ptrint *) (sp + 4 * 4)) = (ptrint) ra;
810 PATCHER_MONITORENTER;
812 /* get the fieldinfo */
814 if (!(m = helper_resolve_methodinfo(um))) {
820 /* patch back original code */
822 *((u4 *) (ra + 0)) = (u4) mcode;
823 *((u1 *) (ra + 4)) = (u1) (mcode >> 32);
825 /* if we show disassembly, we have to skip the nop's */
827 if (opt_showdisassemble)
830 /* patch interfacetable index */
832 *((s4 *) (ra + 2 + 2)) = (s4) (OFFSET(vftbl_t, interfacetable[0]) -
833 sizeof(methodptr) * m->class->index);
835 /* patch method offset */
837 *((s4 *) (ra + 2 + 6 + 2)) =
838 (s4) (sizeof(methodptr) * (m - m->class->methods));
840 PATCHER_MARK_PATCHED_MONITOREXIT;
846 /* patcher_checkcast_instanceof_flags ******************************************
850 <patched call position>
851 b9 00 00 00 00 mov $0x00000000,%ecx
853 *******************************************************************************/
855 bool patcher_checkcast_instanceof_flags(u1 *sp)
858 java_objectheader *o;
860 constant_classref *cr;
863 /* get stuff from the stack */
865 ra = (u1 *) *((ptrint *) (sp + 4 * 4));
866 o = (java_objectheader *) *((ptrint *) (sp + 3 * 4));
867 mcode = *((u8 *) (sp + 1 * 4));
868 cr = (constant_classref *) *((ptrint *) (sp + 0 * 4));
870 /* calculate and set the new return address */
873 *((ptrint *) (sp + 4 * 4)) = (ptrint) ra;
875 PATCHER_MONITORENTER;
877 /* get the fieldinfo */
879 if (!(c = helper_resolve_classinfo(cr))) {
885 /* patch back original code */
887 *((u4 *) (ra + 0)) = (u4) mcode;
888 *((u1 *) (ra + 4)) = (u1) (mcode >> 32);
890 /* if we show disassembly, we have to skip the nop's */
892 if (opt_showdisassemble)
895 /* patch class flags */
897 *((s4 *) (ra + 1)) = (s4) c->flags;
899 PATCHER_MARK_PATCHED_MONITOREXIT;
905 /* patcher_checkcast_instanceof_interface **************************************
909 <patched call position>
910 8b 91 00 00 00 00 mov 0x00000000(%ecx),%edx
911 81 ea 00 00 00 00 sub $0x00000000,%edx
913 0f 8e 00 00 00 00 jle 0x00000000
914 8b 91 00 00 00 00 mov 0x00000000(%ecx),%edx
916 *******************************************************************************/
918 bool patcher_checkcast_instanceof_interface(u1 *sp)
921 java_objectheader *o;
923 constant_classref *cr;
926 /* get stuff from the stack */
928 ra = (u1 *) *((ptrint *) (sp + 4 * 4));
929 o = (java_objectheader *) *((ptrint *) (sp + 3 * 4));
930 mcode = *((u8 *) (sp + 1 * 4));
931 cr = (constant_classref *) *((ptrint *) (sp + 0 * 4));
933 /* calculate and set the new return address */
936 *((ptrint *) (sp + 4 * 4)) = (ptrint) ra;
938 PATCHER_MONITORENTER;
940 /* get the fieldinfo */
942 if (!(c = helper_resolve_classinfo(cr))) {
948 /* patch back original code */
950 *((u4 *) (ra + 0)) = (u4) mcode;
951 *((u1 *) (ra + 4)) = (u1) (mcode >> 32);
953 /* if we show disassembly, we have to skip the nop's */
955 if (opt_showdisassemble)
958 /* patch super class index */
960 *((s4 *) (ra + 6 + 2)) = (s4) c->index;
962 *((s4 *) (ra + 6 + 6 + 2 + 6 + 2)) =
963 (s4) (OFFSET(vftbl_t, interfacetable[0]) -
964 c->index * sizeof(methodptr*));
966 PATCHER_MARK_PATCHED_MONITOREXIT;
972 /* patcher_checkcast_class *****************************************************
976 <patched call position>
977 ba 00 00 00 00 mov $0x00000000,%edx
978 8b 89 00 00 00 00 mov 0x00000000(%ecx),%ecx
979 8b 92 00 00 00 00 mov 0x00000000(%edx),%edx
981 ba 00 00 00 00 mov $0x00000000,%edx
983 *******************************************************************************/
985 bool patcher_checkcast_class(u1 *sp)
988 java_objectheader *o;
990 constant_classref *cr;
993 /* get stuff from the stack */
995 ra = (u1 *) *((ptrint *) (sp + 4 * 4));
996 o = (java_objectheader *) *((ptrint *) (sp + 3 * 4));
997 mcode = *((u8 *) (sp + 1 * 4));
998 cr = (constant_classref *) *((ptrint *) (sp + 0 * 4));
1000 /* calculate and set the new return address */
1003 *((ptrint *) (sp + 4 * 4)) = (ptrint) ra;
1005 PATCHER_MONITORENTER;
1007 /* get the fieldinfo */
1009 if (!(c = helper_resolve_classinfo(cr))) {
1010 PATCHER_MONITOREXIT;
1015 /* patch back original code */
1017 *((u4 *) (ra + 0)) = (u4) mcode;
1018 *((u1 *) (ra + 4)) = (u1) (mcode >> 32);
1020 /* if we show disassembly, we have to skip the nop's */
1022 if (opt_showdisassemble)
1025 /* patch super class' vftbl */
1027 *((ptrint *) (ra + 1)) = (ptrint) c->vftbl;
1028 *((ptrint *) (ra + 5 + 6 + 6 + 2 + 1)) = (ptrint) c->vftbl;
1030 PATCHER_MARK_PATCHED_MONITOREXIT;
1036 /* patcher_instanceof_class ****************************************************
1040 <patched call position>
1041 b9 00 00 00 00 mov $0x0,%ecx
1042 8b 40 14 mov 0x14(%eax),%eax
1043 8b 51 18 mov 0x18(%ecx),%edx
1044 8b 49 14 mov 0x14(%ecx),%ecx
1046 *******************************************************************************/
1048 bool patcher_instanceof_class(u1 *sp)
1051 java_objectheader *o;
1053 constant_classref *cr;
1056 /* get stuff from the stack */
1058 ra = (u1 *) *((ptrint *) (sp + 4 * 4));
1059 o = (java_objectheader *) *((ptrint *) (sp + 3 * 4));
1060 mcode = *((u8 *) (sp + 1 * 4));
1061 cr = (constant_classref *) *((ptrint *) (sp + 0 * 4));
1063 /* calculate and set the new return address */
1066 *((ptrint *) (sp + 4 * 4)) = (ptrint) ra;
1068 PATCHER_MONITORENTER;
1070 /* get the fieldinfo */
1072 if (!(c = helper_resolve_classinfo(cr))) {
1073 PATCHER_MONITOREXIT;
1078 /* patch back original code */
1080 *((u4 *) (ra + 0)) = (u4) mcode;
1081 *((u1 *) (ra + 4)) = (u1) (mcode >> 32);
1083 /* if we show disassembly, we have to skip the nop's */
1085 if (opt_showdisassemble)
1088 /* patch super class' vftbl */
1090 *((ptrint *) (ra + 1)) = (ptrint) c->vftbl;
1092 PATCHER_MARK_PATCHED_MONITOREXIT;
1098 /* patcher_clinit **************************************************************
1100 Is used int PUT/GETSTATIC and native stub.
1104 <patched call position>
1106 *******************************************************************************/
1108 bool patcher_clinit(u1 *sp)
1111 java_objectheader *o;
1115 /* get stuff from the stack */
1117 ra = (u1 *) *((ptrint *) (sp + 4 * 4));
1118 o = (java_objectheader *) *((ptrint *) (sp + 3 * 4));
1119 mcode = *((u8 *) (sp + 1 * 4));
1120 c = (classinfo *) *((ptrint *) (sp + 0 * 4));
1122 /* calculate and set the new return address */
1125 *((ptrint *) (sp + 4 * 4)) = (ptrint) ra;
1127 PATCHER_MONITORENTER;
1129 /* check if the class is initialized */
1131 if (!c->initialized) {
1132 if (!initialize_class(c)) {
1133 PATCHER_MONITOREXIT;
1139 /* patch back original code */
1141 *((u4 *) (ra + 0)) = (u4) mcode;
1142 *((u1 *) (ra + 4)) = (u1) (mcode >> 32);
1144 PATCHER_MARK_PATCHED_MONITOREXIT;
1150 /* patcher_athrow_areturn ******************************************************
1154 <patched call position>
1156 *******************************************************************************/
1158 bool patcher_athrow_areturn(u1 *sp)
1161 java_objectheader *o;
1163 unresolved_class *uc;
1166 /* get stuff from the stack */
1168 ra = (u1 *) *((ptrint *) (sp + 4 * 4));
1169 o = (java_objectheader *) *((ptrint *) (sp + 3 * 4));
1170 mcode = *((u8 *) (sp + 1 * 4));
1171 uc = (unresolved_class *) *((ptrint *) (sp + 0 * 4));
1173 /* calculate and set the new return address */
1176 *((ptrint *) (sp + 4 * 4)) = (ptrint) ra;
1178 PATCHER_MONITORENTER;
1180 /* resolve the class */
1182 if (!resolve_class(uc, resolveEager, false, &c)) {
1183 PATCHER_MONITOREXIT;
1188 /* patch back original code */
1190 *((u4 *) (ra + 0)) = (u4) mcode;
1191 *((u1 *) (ra + 4)) = (u1) (mcode >> 32);
1193 PATCHER_MARK_PATCHED_MONITOREXIT;
1199 /* patcher_resolve_native ******************************************************
1201 Is used in native stub.
1205 <patched call position>
1206 c7 44 24 04 28 90 01 40 movl $0x40019028,0x4(%esp)
1208 *******************************************************************************/
1210 #if !defined(ENABLE_STATICVM)
1211 bool patcher_resolve_native(u1 *sp)
1214 java_objectheader *o;
1219 /* get stuff from the stack */
1221 ra = (u1 *) *((ptrint *) (sp + 4 * 4));
1222 o = (java_objectheader *) *((ptrint *) (sp + 3 * 4));
1223 mcode = *((u8 *) (sp + 1 * 4));
1224 m = (methodinfo *) *((ptrint *) (sp + 0 * 4));
1226 /* calculate and set the new return address */
1229 *((ptrint *) (sp + 4 * 4)) = (ptrint) ra;
1231 PATCHER_MONITORENTER;
1233 /* resolve native function */
1235 if (!(f = native_resolve_function(m))) {
1236 PATCHER_MONITOREXIT;
1241 /* patch back original code */
1243 *((u4 *) (ra + 0)) = (u4) mcode;
1244 *((u1 *) (ra + 4)) = (u1) (mcode >> 32);
1246 /* if we show disassembly, we have to skip the nop's */
1248 if (opt_showdisassemble)
1251 /* patch native function pointer */
1253 *((ptrint *) (ra + 4)) = (ptrint) f;
1255 PATCHER_MARK_PATCHED_MONITOREXIT;
1259 #endif /* !defined(ENABLE_STATICVM) */
1263 * These are local overrides for various environment variables in Emacs.
1264 * Please do not remove this and leave it at the end of the file, where
1265 * Emacs will automagically detect them.
1266 * ---------------------------------------------------------------------
1269 * indent-tabs-mode: t
1273 * vim:noexpandtab:sw=4:ts=4: