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 2421 2005-04-30 13:28:35Z 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 /* patcher_get_putstatic *******************************************************
50 <patched call position>
51 4d 8b 15 86 fe ff ff mov -378(%rip),%r10
53 *******************************************************************************/
55 bool patcher_get_putstatic(u1 *sp)
65 /* get stuff from the stack */
67 ra = (u1 *) *((ptrint *) (sp + 3 * 8));
68 o = (java_objectheader *) *((ptrint *) (sp + 2 * 8));
69 mcode = *((u8 *) (sp + 1 * 8));
70 uf = (unresolved_field *) *((ptrint *) (sp + 0 * 8));
72 beginJavaStack= (void*)(sp + 3 * 8);
74 *dontfillinexceptionstacktrace=true;
76 /* calculate and set the new return address */
79 *((ptrint *) (sp + 3 * 8)) = (ptrint) ra;
81 #if defined(USE_THREADS)
82 /* enter a monitor on the patching position */
84 builtin_monitorenter(o);
86 /* check if the position has already been patched */
89 builtin_monitorexit(o);
95 /* get the fieldinfo */
97 if (!(fi = helper_resolve_fieldinfo(uf))) {
98 *dontfillinexceptionstacktrace=false;
102 /* check if the field's class is initialized */
104 *dontfillinexceptionstacktrace=false;
105 if (!fi->class->initialized) {
108 /*struct native_stackframeinfo {
109 void *oldThreadspecificHeadValue;
110 void **addressOfThreadspecificHead;
112 void *beginOfJavaStackframe; only used if != 0
113 void *returnToFromNative;
115 /* more or less the same as the above sfi setup is done in the assembler code by the prepare/remove functions*/
116 native_stackframeinfo sfi;
117 sfi.returnToFromNative=(void*)ra;
118 sfi.beginOfJavaStackframe=beginJavaStack;
119 sfi.method=0; /*internal*/
120 sfi.addressOfThreadspecificHead=builtin_asm_get_stackframeinfo();
121 sfi.oldThreadspecificHeadValue=*(sfi.addressOfThreadspecificHead);
122 *(sfi.addressOfThreadspecificHead)=&sfi;
124 init=initialize_class(fi->class);
126 *(sfi.addressOfThreadspecificHead)=sfi.oldThreadspecificHeadValue;
134 *dontfillinexceptionstacktrace=false;
136 /* patch back original code */
138 *((u8 *) ra) = mcode;
140 /* if we show disassembly, we have to skip the nop's */
145 /* get RIP offset from machine instruction */
147 offset = *((u4 *) (ra + 3));
149 /* patch the field value's address (+ 7: is the size of the RIP move) */
151 *((ptrint *) (ra + 7 + offset)) = (ptrint) &(fi->value);
153 #if defined(USE_THREADS)
154 /* this position has been patched */
156 o->vftbl = (vftbl_t *) 1;
158 /* leave the monitor on the patching position */
160 builtin_monitorexit(o);
167 /* patcher_get_putfield ********************************************************
171 <patched call position>
172 45 8b 8f 00 00 00 00 mov 0x0(%r15),%r9d
174 *******************************************************************************/
176 bool patcher_get_putfield(u1 *sp)
179 java_objectheader *o;
181 unresolved_field *uf;
184 /* get stuff from the stack */
186 ra = (u1 *) *((ptrint *) (sp + 3 * 8));
187 o = (java_objectheader *) *((ptrint *) (sp + 2 * 8));
188 mcode = *((u8 *) (sp + 1 * 8));
189 uf = (unresolved_field *) *((ptrint *) (sp + 0 * 8));
191 /* calculate and set the new return address */
194 *((ptrint *) (sp + 3 * 8)) = (ptrint) ra;
196 *dontfillinexceptionstacktrace=true;
198 #if defined(USE_THREADS)
199 /* enter a monitor on the patching position */
201 builtin_monitorenter(o);
203 /* check if the position has already been patched */
206 builtin_monitorexit(o);
212 /* get the fieldinfo */
214 if (!(fi = helper_resolve_fieldinfo(uf))) {
215 *dontfillinexceptionstacktrace=false;
219 /* patch back original code */
221 *((u8 *) ra) = mcode;
223 /* if we show disassembly, we have to skip the nop's */
228 /* patch the field's offset: we check for the field type, because the */
229 /* instructions have different lengths */
231 if (IS_FLT_DBL_TYPE(fi->type)) {
232 *((u4 *) (ra + 5)) = (u4) (fi->offset);
237 /* check for special case: %rsp or %r12 as base register */
242 *((u4 *) (ra + 4)) = (u4) (fi->offset);
244 *((u4 *) (ra + 3)) = (u4) (fi->offset);
247 *dontfillinexceptionstacktrace=false;
249 #if defined(USE_THREADS)
250 /* this position has been patched */
252 o->vftbl = (vftbl_t *) 1;
254 /* leave the monitor on the patching position */
256 builtin_monitorexit(o);
263 /* patcher_putfieldconst *******************************************************
267 <patched call position>
268 49 c7 87 10 00 00 00 00 00 00 00 movq $0x0,0x10(%r15)
270 *******************************************************************************/
272 bool patcher_putfieldconst(u1 *sp)
275 java_objectheader *o;
277 unresolved_field *uf;
280 /* get stuff from the stack */
282 ra = (u1 *) *((ptrint *) (sp + 3 * 8));
283 o = (java_objectheader *) *((ptrint *) (sp + 2 * 8));
284 mcode = *((u8 *) (sp + 1 * 8));
285 uf = (unresolved_field *) *((ptrint *) (sp + 0 * 8));
287 /* calculate and set the new return address */
290 *((ptrint *) (sp + 3 * 8)) = (ptrint) ra;
292 *dontfillinexceptionstacktrace=true;
294 #if defined(USE_THREADS)
295 /* enter a monitor on the patching position */
297 builtin_monitorenter(o);
299 /* check if the position has already been patched */
302 builtin_monitorexit(o);
308 /* get the fieldinfo */
310 if (!(fi = helper_resolve_fieldinfo(uf))) {
311 *dontfillinexceptionstacktrace=false;
315 /* patch back original code */
317 *((u8 *) ra) = mcode;
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) || IS_ADR_TYPE(fi->type)) {
327 *((u4 *) (ra + 3)) = (u4) (fi->offset);
328 *((u4 *) (ra + 11 + 3)) = (u4) (fi->offset + 4);
331 *((u4 *) (ra + 3)) = (u4) (fi->offset);
334 *dontfillinexceptionstacktrace=false;
336 #if defined(USE_THREADS)
337 /* this position has been patched */
339 o->vftbl = (vftbl_t *) 1;
341 /* leave the monitor on the patching position */
343 builtin_monitorexit(o);
350 /* patcher_builtin_new *********************************************************
354 48 bf a0 f0 92 00 00 00 00 00 mov $0x92f0a0,%rdi
355 <patched call position>
356 48 b8 00 00 00 00 00 00 00 00 mov $0x0,%rax
359 *******************************************************************************/
361 bool patcher_builtin_new(u1 *sp)
364 java_objectheader *o;
366 constant_classref *cr;
369 /* get stuff from the stack */
371 ra = (u1 *) *((ptrint *) (sp + 3 * 8));
372 o = (java_objectheader *) *((ptrint *) (sp + 2 * 8));
373 mcode = *((u8 *) (sp + 1 * 8));
374 cr = (constant_classref *) *((ptrint *) (sp + 0 * 8));
376 /* calculate and set the new return address */
379 *((ptrint *) (sp + 3 * 8)) = (ptrint) ra;
381 *dontfillinexceptionstacktrace=true;
383 #if defined(USE_THREADS)
384 /* enter a monitor on the patching position */
386 builtin_monitorenter(o);
388 /* check if the position has already been patched */
391 builtin_monitorexit(o);
397 /* get the classinfo */
399 if (!(c = helper_resolve_classinfo(cr))) {
400 *dontfillinexceptionstacktrace=false;
404 /* patch back original code */
406 *((u8 *) (ra + 10)) = mcode;
408 /* patch the classinfo pointer */
410 *((ptrint *) (ra + 2)) = (ptrint) c;
412 /* if we show disassembly, we have to skip the nop's */
417 /* patch new function address */
419 *((ptrint *) (ra + 10 + 2)) = (ptrint) BUILTIN_new;
421 *dontfillinexceptionstacktrace=false;
423 #if defined(USE_THREADS)
424 /* this position has been patched */
426 o->vftbl = (vftbl_t *) 1;
428 /* leave the monitor on the patching position */
430 builtin_monitorexit(o);
437 /* patcher_builtin_newarray ****************************************************
441 48 be 88 13 9b 00 00 00 00 00 mov $0x9b1388,%rsi
442 <patched call position>
443 48 b8 00 00 00 00 00 00 00 00 mov $0x0,%rax
446 *******************************************************************************/
448 bool patcher_builtin_newarray(u1 *sp)
451 java_objectheader *o;
453 constant_classref *cr;
456 /* get stuff from the stack */
458 ra = (u1 *) *((ptrint *) (sp + 3 * 8));
459 o = (java_objectheader *) *((ptrint *) (sp + 2 * 8));
460 mcode = *((u8 *) (sp + 1 * 8));
461 cr = (constant_classref *) *((ptrint *) (sp + 0 * 8));
463 /* calculate and set the new return address */
466 *((ptrint *) (sp + 3 * 8)) = (ptrint) ra;
468 *dontfillinexceptionstacktrace=true;
470 #if defined(USE_THREADS)
471 /* enter a monitor on the patching position */
473 builtin_monitorenter(o);
475 /* check if the position has already been patched */
478 builtin_monitorexit(o);
484 /* get the classinfo */
486 if (!(c = helper_resolve_classinfo(cr))) {
487 *dontfillinexceptionstacktrace=false;
491 /* patch back original code */
493 *((u8 *) (ra + 10)) = mcode;
495 /* patch the class' vftbl pointer */
497 *((ptrint *) (ra + 2)) = (ptrint) c->vftbl;
499 /* if we show disassembly, we have to skip the nop's */
504 /* patch new function address */
506 *((ptrint *) (ra + 10 + 2)) = (ptrint) BUILTIN_newarray;
508 *dontfillinexceptionstacktrace=false;
510 #if defined(USE_THREADS)
511 /* this position has been patched */
513 o->vftbl = (vftbl_t *) 1;
515 /* leave the monitor on the patching position */
517 builtin_monitorexit(o);
524 /* patcher_builtin_multianewarray **********************************************
528 <patched call position>
529 48 bf 02 00 00 00 00 00 00 00 mov $0x2,%rdi
530 48 be 30 40 b2 00 00 00 00 00 mov $0xb24030,%rsi
531 48 89 e2 mov %rsp,%rdx
532 48 b8 7c 96 4b 00 00 00 00 00 mov $0x4b967c,%rax
535 *******************************************************************************/
537 bool patcher_builtin_multianewarray(u1 *sp)
540 java_objectheader *o;
542 constant_classref *cr;
545 /* get stuff from the stack */
547 ra = (u1 *) *((ptrint *) (sp + 3 * 8));
548 o = (java_objectheader *) *((ptrint *) (sp + 2 * 8));
549 mcode = *((u8 *) (sp + 1 * 8));
550 cr = (constant_classref *) *((ptrint *) (sp + 0 * 8));
552 /* calculate and set the new return address */
555 *((ptrint *) (sp + 3 * 8)) = (ptrint) ra;
557 *dontfillinexceptionstacktrace=true;
559 #if defined(USE_THREADS)
560 /* enter a monitor on the patching position */
562 builtin_monitorenter(o);
564 /* check if the position has already been patched */
567 builtin_monitorexit(o);
573 /* get the classinfo */
575 if (!(c = helper_resolve_classinfo(cr))) {
576 *dontfillinexceptionstacktrace=false;
580 /* patch back original code */
582 *((u8 *) ra) = mcode;
584 /* if we show disassembly, we have to skip the nop's */
589 /* patch the class' vftbl pointer */
591 *((ptrint *) (ra + 10 + 2)) = (ptrint) c->vftbl;
593 /* patch new function address */
595 *((ptrint *) (ra + 10 + 10 + 3 + 2)) = (ptrint) BUILTIN_multianewarray;
597 *dontfillinexceptionstacktrace=false;
599 #if defined(USE_THREADS)
600 /* this position has been patched */
602 o->vftbl = (vftbl_t *) 1;
604 /* leave the monitor on the patching position */
606 builtin_monitorexit(o);
613 /* patcher_builtin_checkarraycast **********************************************
617 48 be b8 3f b2 00 00 00 00 00 mov $0xb23fb8,%rsi
618 <patched call position>
619 48 b8 00 00 00 00 00 00 00 00 mov $0x0,%rax
622 *******************************************************************************/
624 bool patcher_builtin_checkarraycast(u1 *sp)
627 java_objectheader *o;
629 constant_classref *cr;
632 /* get stuff from the stack */
634 ra = (u1 *) *((ptrint *) (sp + 3 * 8));
635 o = (java_objectheader *) *((ptrint *) (sp + 2 * 8));
636 mcode = *((u8 *) (sp + 1 * 8));
637 cr = (constant_classref *) *((ptrint *) (sp + 0 * 8));
639 /* calculate and set the new return address */
642 *((ptrint *) (sp + 3 * 8)) = (ptrint) ra;
644 *dontfillinexceptionstacktrace=true;
646 #if defined(USE_THREADS)
647 /* enter a monitor on the patching position */
649 builtin_monitorenter(o);
651 /* check if the position has already been patched */
654 builtin_monitorexit(o);
660 /* get the classinfo */
662 if (!(c = helper_resolve_classinfo(cr))) {
663 *dontfillinexceptionstacktrace=false;
667 /* patch back original code */
669 *((u8 *) (ra + 10)) = mcode;
671 /* patch the class' vftbl pointer */
673 *((ptrint *) (ra + 2)) = (ptrint) c->vftbl;
675 /* if we show disassembly, we have to skip the nop's */
680 /* patch new function address */
682 *((ptrint *) (ra + 10 + 2)) = (ptrint) BUILTIN_checkarraycast;
684 *dontfillinexceptionstacktrace=false;
686 #if defined(USE_THREADS)
687 /* this position has been patched */
689 o->vftbl = (vftbl_t *) 1;
691 /* leave the monitor on the patching position */
693 builtin_monitorexit(o);
700 /* patcher_builtin_arrayinstanceof *********************************************
704 48 be 30 3c b2 00 00 00 00 00 mov $0xb23c30,%rsi
705 <patched call position>
706 48 b8 00 00 00 00 00 00 00 00 mov $0x0,%rax
709 *******************************************************************************/
711 bool patcher_builtin_arrayinstanceof(u1 *sp)
714 java_objectheader *o;
716 constant_classref *cr;
719 /* get stuff from the stack */
721 ra = (u1 *) *((ptrint *) (sp + 3 * 8));
722 o = (java_objectheader *) *((ptrint *) (sp + 2 * 8));
723 mcode = *((u8 *) (sp + 1 * 8));
724 cr = (constant_classref *) *((ptrint *) (sp + 0 * 8));
726 /* calculate and set the new return address */
729 *((ptrint *) (sp + 3 * 8)) = (ptrint) ra;
731 *dontfillinexceptionstacktrace=true;
733 #if defined(USE_THREADS)
734 /* enter a monitor on the patching position */
736 builtin_monitorenter(o);
738 /* check if the position has already been patched */
741 builtin_monitorexit(o);
747 /* get the classinfo */
749 if (!(c = helper_resolve_classinfo(cr))) {
750 *dontfillinexceptionstacktrace=false;
754 /* patch back original code */
756 *((u8 *) (ra + 10)) = mcode;
758 /* patch the class' vftbl pointer */
760 *((ptrint *) (ra + 2)) = (ptrint) c->vftbl;
762 /* if we show disassembly, we have to skip the nop's */
767 /* patch new function address */
769 *((ptrint *) (ra + 10 + 2)) = (ptrint) BUILTIN_arrayinstanceof;
771 *dontfillinexceptionstacktrace=false;
773 #if defined(USE_THREADS)
774 /* this position has been patched */
776 o->vftbl = (vftbl_t *) 1;
778 /* leave the monitor on the patching position */
780 builtin_monitorexit(o);
787 /* patcher_invokestatic_special ************************************************
791 *******************************************************************************/
793 bool patcher_invokestatic_special(u1 *sp)
796 java_objectheader *o;
798 unresolved_method *um;
801 /* get stuff from the stack */
803 ra = (u1 *) *((ptrint *) (sp + 3 * 8));
804 o = (java_objectheader *) *((ptrint *) (sp + 2 * 8));
805 mcode = *((u8 *) (sp + 1 * 8));
806 um = (unresolved_method *) *((ptrint *) (sp + 0 * 8));
808 /* calculate and set the new return address */
811 *((ptrint *) (sp + 3 * 8)) = (ptrint) ra;
813 *dontfillinexceptionstacktrace=true;
815 #if defined(USE_THREADS)
816 /* enter a monitor on the patching position */
818 builtin_monitorenter(o);
820 /* check if the position has already been patched */
823 builtin_monitorexit(o);
829 /* get the fieldinfo */
831 if (!(m = helper_resolve_methodinfo(um))) {
832 *dontfillinexceptionstacktrace=false;
835 /* patch back original code */
837 *((u8 *) ra) = mcode;
839 /* if we show disassembly, we have to skip the nop's */
844 /* patch stubroutine */
846 *((ptrint *) (ra + 2)) = (ptrint) m->stubroutine;
848 *dontfillinexceptionstacktrace=false;
850 #if defined(USE_THREADS)
851 /* this position has been patched */
853 o->vftbl = (vftbl_t *) 1;
855 /* leave the monitor on the patching position */
857 builtin_monitorexit(o);
864 /* patcher_invokevirtual *******************************************************
868 *******************************************************************************/
870 bool patcher_invokevirtual(u1 *sp)
873 java_objectheader *o;
875 unresolved_method *um;
878 /* get stuff from the stack */
880 ra = (u1 *) *((ptrint *) (sp + 3 * 8));
881 o = (java_objectheader *) *((ptrint *) (sp + 2 * 8));
882 mcode = *((u8 *) (sp + 1 * 8));
883 um = (unresolved_method *) *((ptrint *) (sp + 0 * 8));
885 /* calculate and set the new return address */
888 *((ptrint *) (sp + 3 * 8)) = (ptrint) ra;
890 *dontfillinexceptionstacktrace=true;
892 #if defined(USE_THREADS)
893 /* enter a monitor on the patching position */
895 builtin_monitorenter(o);
897 /* check if the position has already been patched */
900 builtin_monitorexit(o);
906 /* get the fieldinfo */
908 if (!(m = helper_resolve_methodinfo(um))) {
909 *dontfillinexceptionstacktrace=false;
913 /* patch back original code */
915 *((u8 *) ra) = mcode;
917 /* if we show disassembly, we have to skip the nop's */
922 /* patch vftbl index */
924 *((s4 *) (ra + 3 + 3)) = (s4) (OFFSET(vftbl_t, table[0]) +
925 sizeof(methodptr) * m->vftblindex);
927 *dontfillinexceptionstacktrace=false;
929 #if defined(USE_THREADS)
930 /* this position has been patched */
932 o->vftbl = (vftbl_t *) 1;
934 /* leave the monitor on the patching position */
936 builtin_monitorexit(o);
943 /* patcher_invokeinterface *****************************************************
947 *******************************************************************************/
949 bool patcher_invokeinterface(u1 *sp)
952 java_objectheader *o;
954 unresolved_method *um;
957 /* get stuff from the stack */
959 ra = (u1 *) *((ptrint *) (sp + 3 * 8));
960 o = (java_objectheader *) *((ptrint *) (sp + 2 * 8));
961 mcode = *((u8 *) (sp + 1 * 8));
962 um = (unresolved_method *) *((ptrint *) (sp + 0 * 8));
964 /* calculate and set the new return address */
967 *((ptrint *) (sp + 3 * 8)) = (ptrint) ra;
969 *dontfillinexceptionstacktrace=true;
971 #if defined(USE_THREADS)
972 /* enter a monitor on the patching position */
974 builtin_monitorenter(o);
976 /* check if the position has already been patched */
979 builtin_monitorexit(o);
985 /* get the fieldinfo */
987 if (!(m = helper_resolve_methodinfo(um))) {
988 *dontfillinexceptionstacktrace=false;
992 /* patch back original code */
994 *((u8 *) ra) = mcode;
996 /* if we show disassembly, we have to skip the nop's */
1001 /* patch interfacetable index */
1003 *((s4 *) (ra + 3 + 3)) = (s4) (OFFSET(vftbl_t, interfacetable[0]) -
1004 sizeof(methodptr) * m->class->index);
1006 /* patch method offset */
1008 *((s4 *) (ra + 3 + 7 + 3)) =
1009 (s4) (sizeof(methodptr) * (m - m->class->methods));
1011 *dontfillinexceptionstacktrace=false;
1013 #if defined(USE_THREADS)
1014 /* this position has been patched */
1016 o->vftbl = (vftbl_t *) 1;
1018 /* leave the monitor on the patching position */
1020 builtin_monitorexit(o);
1027 /* patcher_checkcast_instanceof_flags ******************************************
1031 *******************************************************************************/
1033 bool patcher_checkcast_instanceof_flags(u1 *sp)
1036 java_objectheader *o;
1038 constant_classref *cr;
1041 /* get stuff from the stack */
1043 ra = (u1 *) *((ptrint *) (sp + 3 * 8));
1044 o = (java_objectheader *) *((ptrint *) (sp + 2 * 8));
1045 mcode = *((u8 *) (sp + 1 * 8));
1046 cr = (constant_classref *) *((ptrint *) (sp + 0 * 8));
1048 /* calculate and set the new return address */
1051 *((ptrint *) (sp + 3 * 8)) = (ptrint) ra;
1053 *dontfillinexceptionstacktrace=true;
1055 #if defined(USE_THREADS)
1056 /* enter a monitor on the patching position */
1058 builtin_monitorenter(o);
1060 /* check if the position has already been patched */
1063 builtin_monitorexit(o);
1069 /* get the fieldinfo */
1071 if (!(c = helper_resolve_classinfo(cr))) {
1072 *dontfillinexceptionstacktrace=false;
1076 /* patch back original code */
1078 *((u8 *) ra) = mcode;
1080 /* if we show disassembly, we have to skip the nop's */
1082 if (showdisassemble)
1085 /* patch class flags */
1087 *((s4 *) (ra + 2)) = (s4) c->flags;
1089 *dontfillinexceptionstacktrace=false;
1091 #if defined(USE_THREADS)
1092 /* this position has been patched */
1094 o->vftbl = (vftbl_t *) 1;
1096 /* leave the monitor on the patching position */
1098 builtin_monitorexit(o);
1105 /* patcher_checkcast_instanceof_interface **************************************
1109 *******************************************************************************/
1111 bool patcher_checkcast_instanceof_interface(u1 *sp)
1114 java_objectheader *o;
1116 constant_classref *cr;
1119 /* get stuff from the stack */
1121 ra = (u1 *) *((ptrint *) (sp + 3 * 8));
1122 o = (java_objectheader *) *((ptrint *) (sp + 2 * 8));
1123 mcode = *((u8 *) (sp + 1 * 8));
1124 cr = (constant_classref *) *((ptrint *) (sp + 0 * 8));
1126 /* calculate and set the new return address */
1129 *((ptrint *) (sp + 3 * 8)) = (ptrint) ra;
1131 *dontfillinexceptionstacktrace=true;
1133 #if defined(USE_THREADS)
1134 /* enter a monitor on the patching position */
1136 builtin_monitorenter(o);
1138 /* check if the position has already been patched */
1141 builtin_monitorexit(o);
1147 /* get the fieldinfo */
1149 if (!(c = helper_resolve_classinfo(cr))) {
1150 *dontfillinexceptionstacktrace=false;
1154 /* patch back original code */
1156 *((u8 *) ra) = mcode;
1158 /* if we show disassembly, we have to skip the nop's */
1160 if (showdisassemble)
1163 /* patch super class index */
1165 *((s4 *) (ra + 7 + 3)) = (s4) c->index;
1167 *((s4 *) (ra + 7 + 7 + 3 + 6 + 3)) =
1168 (s4) (OFFSET(vftbl_t, interfacetable[0]) -
1169 c->index * sizeof(methodptr*));
1171 *dontfillinexceptionstacktrace=false;
1173 #if defined(USE_THREADS)
1174 /* this position has been patched */
1176 o->vftbl = (vftbl_t *) 1;
1178 /* leave the monitor on the patching position */
1180 builtin_monitorexit(o);
1187 /* patcher_checkcast_class *****************************************************
1191 *******************************************************************************/
1193 bool patcher_checkcast_class(u1 *sp)
1196 java_objectheader *o;
1198 constant_classref *cr;
1201 /* get stuff from the stack */
1203 ra = (u1 *) *((ptrint *) (sp + 3 * 8));
1204 o = (java_objectheader *) *((ptrint *) (sp + 2 * 8));
1205 mcode = *((u8 *) (sp + 1 * 8));
1206 cr = (constant_classref *) *((ptrint *) (sp + 0 * 8));
1208 /* calculate and set the new return address */
1211 *((ptrint *) (sp + 3 * 8)) = (ptrint) ra;
1213 *dontfillinexceptionstacktrace=true;
1215 #if defined(USE_THREADS)
1216 /* enter a monitor on the patching position */
1218 builtin_monitorenter(o);
1220 /* check if the position has already been patched */
1223 builtin_monitorexit(o);
1229 /* get the fieldinfo */
1231 if (!(c = helper_resolve_classinfo(cr))) {
1232 *dontfillinexceptionstacktrace=false;
1236 /* patch back original code */
1238 *((u8 *) ra) = mcode;
1240 /* if we show disassembly, we have to skip the nop's */
1242 if (showdisassemble)
1245 /* patch super class' vftbl */
1247 *((ptrint *) (ra + 2)) = (ptrint) c->vftbl;
1248 *((ptrint *) (ra + 10 + 7 + 7 + 3 + 2)) = (ptrint) c->vftbl;
1250 *dontfillinexceptionstacktrace=false;
1252 #if defined(USE_THREADS)
1253 /* this position has been patched */
1255 o->vftbl = (vftbl_t *) 1;
1257 /* leave the monitor on the patching position */
1259 builtin_monitorexit(o);
1266 /* patcher_instanceof_class ****************************************************
1270 *******************************************************************************/
1272 bool patcher_instanceof_class(u1 *sp)
1275 java_objectheader *o;
1277 constant_classref *cr;
1280 /* get stuff from the stack */
1282 ra = (u1 *) *((ptrint *) (sp + 3 * 8));
1283 o = (java_objectheader *) *((ptrint *) (sp + 2 * 8));
1284 mcode = *((u8 *) (sp + 1 * 8));
1285 cr = (constant_classref *) *((ptrint *) (sp + 0 * 8));
1287 /* calculate and set the new return address */
1290 *((ptrint *) (sp + 3 * 8)) = (ptrint) ra;
1292 *dontfillinexceptionstacktrace=true;
1294 #if defined(USE_THREADS)
1295 /* enter a monitor on the patching position */
1297 builtin_monitorenter(o);
1299 /* check if the position has already been patched */
1302 builtin_monitorexit(o);
1308 /* get the fieldinfo */
1310 if (!(c = helper_resolve_classinfo(cr))) {
1311 *dontfillinexceptionstacktrace=false;
1315 /* patch back original code */
1317 *((u8 *) ra) = mcode;
1319 /* if we show disassembly, we have to skip the nop's */
1321 if (showdisassemble)
1324 /* patch super class' vftbl */
1326 *((ptrint *) (ra + 2)) = (ptrint) c->vftbl;
1328 *dontfillinexceptionstacktrace=false;
1330 #if defined(USE_THREADS)
1331 /* this position has been patched */
1333 o->vftbl = (vftbl_t *) 1;
1335 /* leave the monitor on the patching position */
1337 builtin_monitorexit(o);
1344 /* patcher_clinit **************************************************************
1348 *******************************************************************************/
1350 bool patcher_clinit(u1 *sp)
1353 java_objectheader *o;
1356 void *beginJavaStack;
1358 /* get stuff from the stack */
1360 ra = (u1 *) *((ptrint *) (sp + 3 * 8));
1361 o = (java_objectheader *) *((ptrint *) (sp + 2 * 8));
1362 mcode = *((u8 *) (sp + 1 * 8));
1363 c = (classinfo *) *((ptrint *) (sp + 0 * 8));
1365 beginJavaStack = (void*) (sp + 3 * 8);
1367 /*printf("beginJavaStack: %p, ra %p\n",beginJavaStack,ra);*/
1368 /* calculate and set the new return address */
1371 *((ptrint *) (sp + 3 * 8)) = (ptrint) ra;
1373 #if defined(USE_THREADS)
1374 /* enter a monitor on the patching position */
1376 builtin_monitorenter(o);
1378 /* check if the position has already been patched */
1381 builtin_monitorexit(o);
1387 /* check if the class is initialized */
1389 if (!c->initialized) {
1392 /*struct native_stackframeinfo {
1393 void *oldThreadspecificHeadValue;
1394 void **addressOfThreadspecificHead;
1396 void *beginOfJavaStackframe; only used if != 0
1397 void *returnToFromNative;
1399 /* more or less the same as the above sfi setup is done in the assembler code by the prepare/remove functions*/
1400 native_stackframeinfo sfi;
1401 sfi.returnToFromNative=(void*)ra;
1402 sfi.beginOfJavaStackframe=beginJavaStack;
1403 sfi.method=0; /*internal*/
1404 sfi.addressOfThreadspecificHead=builtin_asm_get_stackframeinfo();
1405 sfi.oldThreadspecificHeadValue=*(sfi.addressOfThreadspecificHead);
1406 *(sfi.addressOfThreadspecificHead)=&sfi;
1408 init=initialize_class(c);
1410 *(sfi.addressOfThreadspecificHead)=sfi.oldThreadspecificHeadValue;
1418 /* patch back original code */
1420 *((u8 *) ra) = mcode;
1422 #if defined(USE_THREADS)
1423 /* this position has been patched */
1425 o->vftbl = (vftbl_t *) 1;
1427 /* leave the monitor on the patching position */
1429 builtin_monitorexit(o);
1437 * These are local overrides for various environment variables in Emacs.
1438 * Please do not remove this and leave it at the end of the file, where
1439 * Emacs will automagically detect them.
1440 * ---------------------------------------------------------------------
1443 * indent-tabs-mode: t
1447 * vim:noexpandtab:sw=4:ts=4: