1 /* src/vm/jit/x86_64/patcher.c - x86_64 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 2448 2005-05-11 13:03:20Z twisti $
36 #include "vm/jit/x86_64/types.h"
37 #include "vm/builtin.h"
39 #include "vm/initialize.h"
40 #include "vm/options.h"
41 #include "vm/references.h"
42 #include "vm/jit/helper.h"
43 #include "vm/exceptions.h"
46 helper_initialize_class(void* beginOfJavaStack,classinfo *c,u1 *ra) {
47 if (!c->initialized) {
50 /*struct native_stackframeinfo {
51 void *oldThreadspecificHeadValue;
52 void **addressOfThreadspecificHead;
54 void *beginOfJavaStackframe; only used if != 0
55 void *returnToFromNative;
57 /* more or less the same as the above sfi setup is done in the assembler code by the prepare/remove functions*/
58 native_stackframeinfo sfi;
59 sfi.returnToFromNative=ra;
60 sfi.beginOfJavaStackframe=beginOfJavaStack;
61 sfi.method=0; /*internal*/
62 sfi.addressOfThreadspecificHead=builtin_asm_get_stackframeinfo();
63 sfi.oldThreadspecificHeadValue=*(sfi.addressOfThreadspecificHead);
64 *(sfi.addressOfThreadspecificHead)=&sfi;
66 /*printf("calling static initializer (helper_initialize_class), returnaddress=%p for class %s\n",ra,c->name->text);*/
68 init=initialize_class(c);
70 *(sfi.addressOfThreadspecificHead)=sfi.oldThreadspecificHeadValue;
79 /* patcher_get_putstatic *******************************************************
83 <patched call position>
84 4d 8b 15 86 fe ff ff mov -378(%rip),%r10
86 *******************************************************************************/
88 bool patcher_get_putstatic(u1 *sp)
98 /* get stuff from the stack */
100 ra = (u1 *) *((ptrint *) (sp + 3 * 8));
101 o = (java_objectheader *) *((ptrint *) (sp + 2 * 8));
102 mcode = *((u8 *) (sp + 1 * 8));
103 uf = (unresolved_field *) *((ptrint *) (sp + 0 * 8));
105 beginJavaStack= (void*)(sp + 3 * 8);
107 *dontfillinexceptionstacktrace=true;
109 /* calculate and set the new return address */
112 *((ptrint *) (sp + 3 * 8)) = (ptrint) ra;
114 #if defined(USE_THREADS)
115 /* enter a monitor on the patching position */
117 builtin_monitorenter(o);
119 /* check if the position has already been patched */
122 builtin_monitorexit(o);
123 *dontfillinexceptionstacktrace=false;
128 /* get the fieldinfo */
130 if (!(fi = helper_resolve_fieldinfo(uf))) {
131 *dontfillinexceptionstacktrace=false;
134 /* check if the field's class is initialized */
136 *dontfillinexceptionstacktrace=false;
137 if (!helper_initialize_class(beginJavaStack,fi->class,ra)) return false;
140 /* patch back original code */
142 *((u8 *) ra) = mcode;
144 /* if we show disassembly, we have to skip the nop's */
149 /* get RIP offset from machine instruction */
151 offset = *((u4 *) (ra + 3));
153 /* patch the field value's address (+ 7: is the size of the RIP move) */
155 *((ptrint *) (ra + 7 + offset)) = (ptrint) &(fi->value);
157 #if defined(USE_THREADS)
158 /* this position has been patched */
160 o->vftbl = (vftbl_t *) 1;
162 /* leave the monitor on the patching position */
164 *dontfillinexceptionstacktrace=true;
165 builtin_monitorexit(o);
166 *dontfillinexceptionstacktrace=false;
174 /* patcher_get_putfield ********************************************************
178 <patched call position>
179 45 8b 8f 00 00 00 00 mov 0x0(%r15),%r9d
181 *******************************************************************************/
183 bool patcher_get_putfield(u1 *sp)
186 java_objectheader *o;
188 unresolved_field *uf;
191 /* get stuff from the stack */
193 ra = (u1 *) *((ptrint *) (sp + 3 * 8));
194 o = (java_objectheader *) *((ptrint *) (sp + 2 * 8));
195 mcode = *((u8 *) (sp + 1 * 8));
196 uf = (unresolved_field *) *((ptrint *) (sp + 0 * 8));
198 /* calculate and set the new return address */
201 *((ptrint *) (sp + 3 * 8)) = (ptrint) ra;
203 *dontfillinexceptionstacktrace=true;
205 #if defined(USE_THREADS)
206 /* enter a monitor on the patching position */
208 builtin_monitorenter(o);
210 /* check if the position has already been patched */
213 builtin_monitorexit(o);
214 *dontfillinexceptionstacktrace=false;
219 /* get the fieldinfo */
221 if (!(fi = helper_resolve_fieldinfo(uf))) {
222 *dontfillinexceptionstacktrace=false;
226 /* patch back original code */
228 *((u8 *) ra) = mcode;
230 /* if we show disassembly, we have to skip the nop's */
235 /* patch the field's offset: we check for the field type, because the */
236 /* instructions have different lengths */
238 if (IS_FLT_DBL_TYPE(fi->type)) {
239 *((u4 *) (ra + 5)) = (u4) (fi->offset);
244 /* check for special case: %rsp or %r12 as base register */
249 *((u4 *) (ra + 4)) = (u4) (fi->offset);
251 *((u4 *) (ra + 3)) = (u4) (fi->offset);
255 #if defined(USE_THREADS)
256 /* this position has been patched */
258 o->vftbl = (vftbl_t *) 1;
260 /* leave the monitor on the patching position */
262 builtin_monitorexit(o);
265 *dontfillinexceptionstacktrace=false;
271 /* patcher_putfieldconst *******************************************************
275 <patched call position>
276 49 c7 87 10 00 00 00 00 00 00 00 movq $0x0,0x10(%r15)
278 *******************************************************************************/
280 bool patcher_putfieldconst(u1 *sp)
283 java_objectheader *o;
285 unresolved_field *uf;
288 /* get stuff from the stack */
290 ra = (u1 *) *((ptrint *) (sp + 3 * 8));
291 o = (java_objectheader *) *((ptrint *) (sp + 2 * 8));
292 mcode = *((u8 *) (sp + 1 * 8));
293 uf = (unresolved_field *) *((ptrint *) (sp + 0 * 8));
295 /* calculate and set the new return address */
298 *((ptrint *) (sp + 3 * 8)) = (ptrint) ra;
300 *dontfillinexceptionstacktrace=true;
302 #if defined(USE_THREADS)
303 /* enter a monitor on the patching position */
305 builtin_monitorenter(o);
307 /* check if the position has already been patched */
310 builtin_monitorexit(o);
316 /* get the fieldinfo */
318 if (!(fi = helper_resolve_fieldinfo(uf))) {
319 *dontfillinexceptionstacktrace=false;
323 /* patch back original code */
325 *((u8 *) ra) = mcode;
327 /* if we show disassembly, we have to skip the nop's */
332 /* handle special case when the base register is %r12 */
334 if (*(ra + 2) == 0x84)
337 /* patch the field's offset */
339 if (IS_2_WORD_TYPE(fi->type) || IS_ADR_TYPE(fi->type)) {
340 *((u4 *) (ra + 3)) = (u4) (fi->offset);
341 *((u4 *) (ra + 11 + 3)) = (u4) (fi->offset + 4);
344 *((u4 *) (ra + 3)) = (u4) (fi->offset);
348 #if defined(USE_THREADS)
349 /* this position has been patched */
351 o->vftbl = (vftbl_t *) 1;
353 /* leave the monitor on the patching position */
355 builtin_monitorexit(o);
357 *dontfillinexceptionstacktrace=false;
363 /* patcher_builtin_new *********************************************************
367 48 bf a0 f0 92 00 00 00 00 00 mov $0x92f0a0,%rdi
368 <patched call position>
369 48 b8 00 00 00 00 00 00 00 00 mov $0x0,%rax
372 *******************************************************************************/
374 bool patcher_builtin_new(u1 *sp)
377 java_objectheader *o;
379 constant_classref *cr;
381 void *beginJavaStack;
382 /* get stuff from the stack */
384 ra = (u1 *) *((ptrint *) (sp + 3 * 8));
385 o = (java_objectheader *) *((ptrint *) (sp + 2 * 8));
386 mcode = *((u8 *) (sp + 1 * 8));
387 cr = (constant_classref *) *((ptrint *) (sp + 0 * 8));
388 beginJavaStack = (void*) (sp+3*8);
390 /* calculate and set the new return address */
393 *((ptrint *) (sp + 3 * 8)) = (ptrint) ra;
395 *dontfillinexceptionstacktrace=true;
397 #if defined(USE_THREADS)
398 /* enter a monitor on the patching position */
400 builtin_monitorenter(o);
402 /* check if the position has already been patched */
405 builtin_monitorexit(o);
406 *dontfillinexceptionstacktrace=false;
411 /* get the classinfo */
413 if (!(c = helper_resolve_classinfo(cr))) {
414 *dontfillinexceptionstacktrace=false;
415 /*should here be an monitorexit too ?*/
419 *dontfillinexceptionstacktrace=false;
420 /*printf("ra:%p\n",ra);*/
421 if (!helper_initialize_class(beginJavaStack,c,ra+5)) return false;
423 /* patch back original code */
425 *((u8 *) (ra + 10)) = mcode;
427 /* patch the classinfo pointer */
429 *((ptrint *) (ra + 2)) = (ptrint) c;
431 /* if we show disassembly, we have to skip the nop's */
436 /* patch new function address */
438 *((ptrint *) (ra + 10 + 2)) = (ptrint) BUILTIN_new;
441 #if defined(USE_THREADS)
442 /* this position has been patched */
444 o->vftbl = (vftbl_t *) 1;
446 /* leave the monitor on the patching position */
447 *dontfillinexceptionstacktrace=true;
448 builtin_monitorexit(o);
449 *dontfillinexceptionstacktrace=false;
457 /* patcher_builtin_newarray ****************************************************
461 48 be 88 13 9b 00 00 00 00 00 mov $0x9b1388,%rsi
462 <patched call position>
463 48 b8 00 00 00 00 00 00 00 00 mov $0x0,%rax
466 *******************************************************************************/
468 bool patcher_builtin_newarray(u1 *sp)
471 java_objectheader *o;
473 constant_classref *cr;
476 /* get stuff from the stack */
478 ra = (u1 *) *((ptrint *) (sp + 3 * 8));
479 o = (java_objectheader *) *((ptrint *) (sp + 2 * 8));
480 mcode = *((u8 *) (sp + 1 * 8));
481 cr = (constant_classref *) *((ptrint *) (sp + 0 * 8));
483 /* calculate and set the new return address */
486 *((ptrint *) (sp + 3 * 8)) = (ptrint) ra;
488 *dontfillinexceptionstacktrace=true;
490 #if defined(USE_THREADS)
491 /* enter a monitor on the patching position */
493 builtin_monitorenter(o);
495 /* check if the position has already been patched */
498 builtin_monitorexit(o);
499 *dontfillinexceptionstacktrace=false;
504 /* get the classinfo */
506 if (!(c = helper_resolve_classinfo(cr))) {
507 *dontfillinexceptionstacktrace=false;
511 /* patch back original code */
513 *((u8 *) (ra + 10)) = mcode;
515 /* patch the class' vftbl pointer */
517 *((ptrint *) (ra + 2)) = (ptrint) c->vftbl;
519 /* if we show disassembly, we have to skip the nop's */
524 /* patch new function address */
526 *((ptrint *) (ra + 10 + 2)) = (ptrint) BUILTIN_newarray;
529 #if defined(USE_THREADS)
530 /* this position has been patched */
532 o->vftbl = (vftbl_t *) 1;
534 /* leave the monitor on the patching position */
536 builtin_monitorexit(o);
539 *dontfillinexceptionstacktrace=false;
545 /* patcher_builtin_multianewarray **********************************************
549 <patched call position>
550 48 bf 02 00 00 00 00 00 00 00 mov $0x2,%rdi
551 48 be 30 40 b2 00 00 00 00 00 mov $0xb24030,%rsi
552 48 89 e2 mov %rsp,%rdx
553 48 b8 7c 96 4b 00 00 00 00 00 mov $0x4b967c,%rax
556 *******************************************************************************/
558 bool patcher_builtin_multianewarray(u1 *sp)
561 java_objectheader *o;
563 constant_classref *cr;
566 /* get stuff from the stack */
568 ra = (u1 *) *((ptrint *) (sp + 3 * 8));
569 o = (java_objectheader *) *((ptrint *) (sp + 2 * 8));
570 mcode = *((u8 *) (sp + 1 * 8));
571 cr = (constant_classref *) *((ptrint *) (sp + 0 * 8));
573 /* calculate and set the new return address */
576 *((ptrint *) (sp + 3 * 8)) = (ptrint) ra;
578 *dontfillinexceptionstacktrace=true;
580 #if defined(USE_THREADS)
581 /* enter a monitor on the patching position */
583 builtin_monitorenter(o);
585 /* check if the position has already been patched */
588 builtin_monitorexit(o);
589 *dontfillinexceptionstacktrace=false;
594 /* get the classinfo */
596 if (!(c = helper_resolve_classinfo(cr))) {
597 *dontfillinexceptionstacktrace=false;
601 /* patch back original code */
603 *((u8 *) ra) = mcode;
605 /* if we show disassembly, we have to skip the nop's */
610 /* patch the class' vftbl pointer */
612 *((ptrint *) (ra + 10 + 2)) = (ptrint) c->vftbl;
614 /* patch new function address */
616 *((ptrint *) (ra + 10 + 10 + 3 + 2)) = (ptrint) BUILTIN_multianewarray;
619 #if defined(USE_THREADS)
620 /* this position has been patched */
622 o->vftbl = (vftbl_t *) 1;
624 /* leave the monitor on the patching position */
626 builtin_monitorexit(o);
628 *dontfillinexceptionstacktrace=false;
634 /* patcher_builtin_arraycheckcast **********************************************
638 48 be b8 3f b2 00 00 00 00 00 mov $0xb23fb8,%rsi
639 <patched call position>
640 48 b8 00 00 00 00 00 00 00 00 mov $0x0,%rax
643 *******************************************************************************/
645 bool patcher_builtin_arraycheckcast(u1 *sp)
648 java_objectheader *o;
650 constant_classref *cr;
653 /* get stuff from the stack */
655 ra = (u1 *) *((ptrint *) (sp + 3 * 8));
656 o = (java_objectheader *) *((ptrint *) (sp + 2 * 8));
657 mcode = *((u8 *) (sp + 1 * 8));
658 cr = (constant_classref *) *((ptrint *) (sp + 0 * 8));
660 /* calculate and set the new return address */
663 *((ptrint *) (sp + 3 * 8)) = (ptrint) ra;
665 *dontfillinexceptionstacktrace=true;
667 #if defined(USE_THREADS)
668 /* enter a monitor on the patching position */
670 builtin_monitorenter(o);
672 /* check if the position has already been patched */
675 builtin_monitorexit(o);
676 *dontfillinexceptionstacktrace=false;
681 /* get the classinfo */
683 if (!(c = helper_resolve_classinfo(cr))) {
684 *dontfillinexceptionstacktrace=false;
688 /* patch back original code */
690 *((u8 *) (ra + 10)) = mcode;
692 /* patch the class' vftbl pointer */
694 *((ptrint *) (ra + 2)) = (ptrint) c->vftbl;
696 /* if we show disassembly, we have to skip the nop's */
701 /* patch new function address */
703 *((ptrint *) (ra + 10 + 2)) = (ptrint) BUILTIN_arraycheckcast;
706 #if defined(USE_THREADS)
707 /* this position has been patched */
709 o->vftbl = (vftbl_t *) 1;
711 /* leave the monitor on the patching position */
713 builtin_monitorexit(o);
715 *dontfillinexceptionstacktrace=false;
720 /* patcher_builtin_arrayinstanceof *********************************************
724 48 be 30 3c b2 00 00 00 00 00 mov $0xb23c30,%rsi
725 <patched call position>
726 48 b8 00 00 00 00 00 00 00 00 mov $0x0,%rax
729 *******************************************************************************/
731 bool patcher_builtin_arrayinstanceof(u1 *sp)
734 java_objectheader *o;
736 constant_classref *cr;
739 /* get stuff from the stack */
741 ra = (u1 *) *((ptrint *) (sp + 3 * 8));
742 o = (java_objectheader *) *((ptrint *) (sp + 2 * 8));
743 mcode = *((u8 *) (sp + 1 * 8));
744 cr = (constant_classref *) *((ptrint *) (sp + 0 * 8));
746 /* calculate and set the new return address */
749 *((ptrint *) (sp + 3 * 8)) = (ptrint) ra;
751 *dontfillinexceptionstacktrace=true;
753 #if defined(USE_THREADS)
754 /* enter a monitor on the patching position */
756 builtin_monitorenter(o);
758 /* check if the position has already been patched */
761 builtin_monitorexit(o);
767 /* get the classinfo */
769 if (!(c = helper_resolve_classinfo(cr))) {
770 *dontfillinexceptionstacktrace=false;
774 /* patch back original code */
776 *((u8 *) (ra + 10)) = mcode;
778 /* patch the class' vftbl pointer */
780 *((ptrint *) (ra + 2)) = (ptrint) c->vftbl;
782 /* if we show disassembly, we have to skip the nop's */
787 /* patch new function address */
789 *((ptrint *) (ra + 10 + 2)) = (ptrint) BUILTIN_arrayinstanceof;
792 #if defined(USE_THREADS)
793 /* this position has been patched */
795 o->vftbl = (vftbl_t *) 1;
797 /* leave the monitor on the patching position */
799 builtin_monitorexit(o);
801 *dontfillinexceptionstacktrace=false;
806 /* patcher_invokestatic_special ************************************************
810 *******************************************************************************/
812 bool patcher_invokestatic_special(u1 *sp)
815 java_objectheader *o;
817 unresolved_method *um;
820 /* get stuff from the stack */
822 ra = (u1 *) *((ptrint *) (sp + 3 * 8));
823 o = (java_objectheader *) *((ptrint *) (sp + 2 * 8));
824 mcode = *((u8 *) (sp + 1 * 8));
825 um = (unresolved_method *) *((ptrint *) (sp + 0 * 8));
827 /* calculate and set the new return address */
830 *((ptrint *) (sp + 3 * 8)) = (ptrint) ra;
832 *dontfillinexceptionstacktrace=true;
834 #if defined(USE_THREADS)
835 /* enter a monitor on the patching position */
837 builtin_monitorenter(o);
839 /* check if the position has already been patched */
842 builtin_monitorexit(o);
843 *dontfillinexceptionstacktrace=false;
848 /* get the fieldinfo */
850 if (!(m = helper_resolve_methodinfo(um))) {
851 *dontfillinexceptionstacktrace=false;
854 /* patch back original code */
856 *((u8 *) ra) = mcode;
858 /* if we show disassembly, we have to skip the nop's */
863 /* patch stubroutine */
865 *((ptrint *) (ra + 2)) = (ptrint) m->stubroutine;
868 #if defined(USE_THREADS)
869 /* this position has been patched */
871 o->vftbl = (vftbl_t *) 1;
873 /* leave the monitor on the patching position */
875 builtin_monitorexit(o);
877 *dontfillinexceptionstacktrace=false;
882 /* patcher_invokevirtual *******************************************************
886 *******************************************************************************/
888 bool patcher_invokevirtual(u1 *sp)
891 java_objectheader *o;
893 unresolved_method *um;
896 /* get stuff from the stack */
898 ra = (u1 *) *((ptrint *) (sp + 3 * 8));
899 o = (java_objectheader *) *((ptrint *) (sp + 2 * 8));
900 mcode = *((u8 *) (sp + 1 * 8));
901 um = (unresolved_method *) *((ptrint *) (sp + 0 * 8));
903 /* calculate and set the new return address */
906 *((ptrint *) (sp + 3 * 8)) = (ptrint) ra;
908 *dontfillinexceptionstacktrace=true;
910 #if defined(USE_THREADS)
911 /* enter a monitor on the patching position */
913 builtin_monitorenter(o);
915 /* check if the position has already been patched */
918 builtin_monitorexit(o);
919 *dontfillinexceptionstacktrace=false;
924 /* get the fieldinfo */
926 if (!(m = helper_resolve_methodinfo(um))) {
927 *dontfillinexceptionstacktrace=false;
931 /* patch back original code */
933 *((u8 *) ra) = mcode;
935 /* if we show disassembly, we have to skip the nop's */
940 /* patch vftbl index */
942 *((s4 *) (ra + 3 + 3)) = (s4) (OFFSET(vftbl_t, table[0]) +
943 sizeof(methodptr) * m->vftblindex);
946 #if defined(USE_THREADS)
947 /* this position has been patched */
949 o->vftbl = (vftbl_t *) 1;
951 /* leave the monitor on the patching position */
953 builtin_monitorexit(o);
955 *dontfillinexceptionstacktrace=false;
960 /* patcher_invokeinterface *****************************************************
964 *******************************************************************************/
966 bool patcher_invokeinterface(u1 *sp)
969 java_objectheader *o;
971 unresolved_method *um;
974 /* get stuff from the stack */
976 ra = (u1 *) *((ptrint *) (sp + 3 * 8));
977 o = (java_objectheader *) *((ptrint *) (sp + 2 * 8));
978 mcode = *((u8 *) (sp + 1 * 8));
979 um = (unresolved_method *) *((ptrint *) (sp + 0 * 8));
981 /* calculate and set the new return address */
984 *((ptrint *) (sp + 3 * 8)) = (ptrint) ra;
986 *dontfillinexceptionstacktrace=true;
988 #if defined(USE_THREADS)
989 /* enter a monitor on the patching position */
991 builtin_monitorenter(o);
993 /* check if the position has already been patched */
996 builtin_monitorexit(o);
997 *dontfillinexceptionstacktrace=true;
1002 /* get the fieldinfo */
1004 if (!(m = helper_resolve_methodinfo(um))) {
1005 *dontfillinexceptionstacktrace=false;
1009 /* patch back original code */
1011 *((u8 *) ra) = mcode;
1013 /* if we show disassembly, we have to skip the nop's */
1015 if (showdisassemble)
1018 /* patch interfacetable index */
1020 *((s4 *) (ra + 3 + 3)) = (s4) (OFFSET(vftbl_t, interfacetable[0]) -
1021 sizeof(methodptr) * m->class->index);
1023 /* patch method offset */
1025 *((s4 *) (ra + 3 + 7 + 3)) =
1026 (s4) (sizeof(methodptr) * (m - m->class->methods));
1029 #if defined(USE_THREADS)
1030 /* this position has been patched */
1032 o->vftbl = (vftbl_t *) 1;
1034 /* leave the monitor on the patching position */
1036 builtin_monitorexit(o);
1038 *dontfillinexceptionstacktrace=false;
1043 /* patcher_checkcast_instanceof_flags ******************************************
1047 *******************************************************************************/
1049 bool patcher_checkcast_instanceof_flags(u1 *sp)
1052 java_objectheader *o;
1054 constant_classref *cr;
1057 /* get stuff from the stack */
1059 ra = (u1 *) *((ptrint *) (sp + 3 * 8));
1060 o = (java_objectheader *) *((ptrint *) (sp + 2 * 8));
1061 mcode = *((u8 *) (sp + 1 * 8));
1062 cr = (constant_classref *) *((ptrint *) (sp + 0 * 8));
1064 /* calculate and set the new return address */
1067 *((ptrint *) (sp + 3 * 8)) = (ptrint) ra;
1069 *dontfillinexceptionstacktrace=true;
1071 #if defined(USE_THREADS)
1072 /* enter a monitor on the patching position */
1074 builtin_monitorenter(o);
1076 /* check if the position has already been patched */
1079 builtin_monitorexit(o);
1080 *dontfillinexceptionstacktrace=false;
1085 /* get the fieldinfo */
1087 if (!(c = helper_resolve_classinfo(cr))) {
1088 *dontfillinexceptionstacktrace=false;
1092 /* patch back original code */
1094 *((u8 *) ra) = mcode;
1096 /* if we show disassembly, we have to skip the nop's */
1098 if (showdisassemble)
1101 /* patch class flags */
1103 *((s4 *) (ra + 2)) = (s4) c->flags;
1106 #if defined(USE_THREADS)
1107 /* this position has been patched */
1109 o->vftbl = (vftbl_t *) 1;
1111 /* leave the monitor on the patching position */
1113 builtin_monitorexit(o);
1115 *dontfillinexceptionstacktrace=false;
1120 /* patcher_checkcast_instanceof_interface **************************************
1124 *******************************************************************************/
1126 bool patcher_checkcast_instanceof_interface(u1 *sp)
1129 java_objectheader *o;
1131 constant_classref *cr;
1134 /* get stuff from the stack */
1136 ra = (u1 *) *((ptrint *) (sp + 3 * 8));
1137 o = (java_objectheader *) *((ptrint *) (sp + 2 * 8));
1138 mcode = *((u8 *) (sp + 1 * 8));
1139 cr = (constant_classref *) *((ptrint *) (sp + 0 * 8));
1141 /* calculate and set the new return address */
1144 *((ptrint *) (sp + 3 * 8)) = (ptrint) ra;
1146 *dontfillinexceptionstacktrace=true;
1148 #if defined(USE_THREADS)
1149 /* enter a monitor on the patching position */
1151 builtin_monitorenter(o);
1153 /* check if the position has already been patched */
1156 builtin_monitorexit(o);
1157 *dontfillinexceptionstacktrace=false;
1162 /* get the fieldinfo */
1164 if (!(c = helper_resolve_classinfo(cr))) {
1165 *dontfillinexceptionstacktrace=false;
1169 /* patch back original code */
1171 *((u8 *) ra) = mcode;
1173 /* if we show disassembly, we have to skip the nop's */
1175 if (showdisassemble)
1178 /* patch super class index */
1180 *((s4 *) (ra + 7 + 3)) = (s4) c->index;
1182 *((s4 *) (ra + 7 + 7 + 3 + 6 + 3)) =
1183 (s4) (OFFSET(vftbl_t, interfacetable[0]) -
1184 c->index * sizeof(methodptr*));
1187 #if defined(USE_THREADS)
1188 /* this position has been patched */
1190 o->vftbl = (vftbl_t *) 1;
1192 /* leave the monitor on the patching position */
1194 builtin_monitorexit(o);
1196 *dontfillinexceptionstacktrace=false;
1201 /* patcher_checkcast_class *****************************************************
1205 *******************************************************************************/
1207 bool patcher_checkcast_class(u1 *sp)
1210 java_objectheader *o;
1212 constant_classref *cr;
1215 /* get stuff from the stack */
1217 ra = (u1 *) *((ptrint *) (sp + 3 * 8));
1218 o = (java_objectheader *) *((ptrint *) (sp + 2 * 8));
1219 mcode = *((u8 *) (sp + 1 * 8));
1220 cr = (constant_classref *) *((ptrint *) (sp + 0 * 8));
1222 /* calculate and set the new return address */
1225 *((ptrint *) (sp + 3 * 8)) = (ptrint) ra;
1227 *dontfillinexceptionstacktrace=true;
1229 #if defined(USE_THREADS)
1230 /* enter a monitor on the patching position */
1232 builtin_monitorenter(o);
1234 /* check if the position has already been patched */
1237 builtin_monitorexit(o);
1238 *dontfillinexceptionstacktrace=false;
1243 /* get the fieldinfo */
1245 if (!(c = helper_resolve_classinfo(cr))) {
1246 *dontfillinexceptionstacktrace=false;
1250 /* patch back original code */
1252 *((u8 *) ra) = mcode;
1254 /* if we show disassembly, we have to skip the nop's */
1256 if (showdisassemble)
1259 /* patch super class' vftbl */
1261 *((ptrint *) (ra + 2)) = (ptrint) c->vftbl;
1262 *((ptrint *) (ra + 10 + 7 + 7 + 3 + 2)) = (ptrint) c->vftbl;
1265 #if defined(USE_THREADS)
1266 /* this position has been patched */
1268 o->vftbl = (vftbl_t *) 1;
1270 /* leave the monitor on the patching position */
1272 builtin_monitorexit(o);
1274 *dontfillinexceptionstacktrace=false;
1279 /* patcher_instanceof_class ****************************************************
1283 *******************************************************************************/
1285 bool patcher_instanceof_class(u1 *sp)
1288 java_objectheader *o;
1290 constant_classref *cr;
1293 /* get stuff from the stack */
1295 ra = (u1 *) *((ptrint *) (sp + 3 * 8));
1296 o = (java_objectheader *) *((ptrint *) (sp + 2 * 8));
1297 mcode = *((u8 *) (sp + 1 * 8));
1298 cr = (constant_classref *) *((ptrint *) (sp + 0 * 8));
1300 /* calculate and set the new return address */
1303 *((ptrint *) (sp + 3 * 8)) = (ptrint) ra;
1305 *dontfillinexceptionstacktrace=true;
1307 #if defined(USE_THREADS)
1308 /* enter a monitor on the patching position */
1310 builtin_monitorenter(o);
1312 /* check if the position has already been patched */
1315 builtin_monitorexit(o);
1316 *dontfillinexceptionstacktrace=false;
1321 /* get the fieldinfo */
1323 if (!(c = helper_resolve_classinfo(cr))) {
1324 *dontfillinexceptionstacktrace=false;
1328 /* patch back original code */
1330 *((u8 *) ra) = mcode;
1332 /* if we show disassembly, we have to skip the nop's */
1334 if (showdisassemble)
1337 /* patch super class' vftbl */
1339 *((ptrint *) (ra + 2)) = (ptrint) c->vftbl;
1342 #if defined(USE_THREADS)
1343 /* this position has been patched */
1345 o->vftbl = (vftbl_t *) 1;
1347 /* leave the monitor on the patching position */
1349 builtin_monitorexit(o);
1351 *dontfillinexceptionstacktrace=false;
1356 /* patcher_clinit **************************************************************
1360 *******************************************************************************/
1362 bool patcher_clinit(u1 *sp)
1365 java_objectheader *o;
1368 void *beginJavaStack;
1370 /* get stuff from the stack */
1372 ra = (u1 *) *((ptrint *) (sp + 3 * 8));
1373 o = (java_objectheader *) *((ptrint *) (sp + 2 * 8));
1374 mcode = *((u8 *) (sp + 1 * 8));
1375 c = (classinfo *) *((ptrint *) (sp + 0 * 8));
1377 beginJavaStack = (void*) (sp + 3 * 8);
1379 /*printf("beginJavaStack: %p, ra %p\n",beginJavaStack,ra);*/
1380 /* calculate and set the new return address */
1383 *((ptrint *) (sp + 3 * 8)) = (ptrint) ra;
1385 #if defined(USE_THREADS)
1386 /* enter a monitor on the patching position */
1388 builtin_monitorenter(o);
1390 /* check if the position has already been patched */
1393 builtin_monitorexit(o);
1394 *dontfillinexceptionstacktrace=false;
1399 /* check if the class is initialized */
1400 *dontfillinexceptionstacktrace=false;
1401 if (!helper_initialize_class(beginJavaStack,c,ra)) return false;
1403 /* patch back original code */
1405 *((u8 *) ra) = mcode;
1407 #if defined(USE_THREADS)
1408 /* this position has been patched */
1410 o->vftbl = (vftbl_t *) 1;
1412 /* leave the monitor on the patching position */
1413 *dontfillinexceptionstacktrace=true;
1414 builtin_monitorexit(o);
1415 *dontfillinexceptionstacktrace=false;
1424 * These are local overrides for various environment variables in Emacs.
1425 * Please do not remove this and leave it at the end of the file, where
1426 * Emacs will automagically detect them.
1427 * ---------------------------------------------------------------------
1430 * indent-tabs-mode: t
1434 * vim:noexpandtab:sw=4:ts=4: