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 2424 2005-04-30 13:45:06Z jowenn $
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 /* patch the field's offset */
334 if (IS_2_WORD_TYPE(fi->type) || IS_ADR_TYPE(fi->type)) {
335 *((u4 *) (ra + 3)) = (u4) (fi->offset);
336 *((u4 *) (ra + 11 + 3)) = (u4) (fi->offset + 4);
339 *((u4 *) (ra + 3)) = (u4) (fi->offset);
343 #if defined(USE_THREADS)
344 /* this position has been patched */
346 o->vftbl = (vftbl_t *) 1;
348 /* leave the monitor on the patching position */
350 builtin_monitorexit(o);
352 *dontfillinexceptionstacktrace=false;
358 /* patcher_builtin_new *********************************************************
362 48 bf a0 f0 92 00 00 00 00 00 mov $0x92f0a0,%rdi
363 <patched call position>
364 48 b8 00 00 00 00 00 00 00 00 mov $0x0,%rax
367 *******************************************************************************/
369 bool patcher_builtin_new(u1 *sp)
372 java_objectheader *o;
374 constant_classref *cr;
376 void *beginJavaStack;
377 /* get stuff from the stack */
379 ra = (u1 *) *((ptrint *) (sp + 3 * 8));
380 o = (java_objectheader *) *((ptrint *) (sp + 2 * 8));
381 mcode = *((u8 *) (sp + 1 * 8));
382 cr = (constant_classref *) *((ptrint *) (sp + 0 * 8));
383 beginJavaStack = (void*) (sp+3*8);
385 /* calculate and set the new return address */
388 *((ptrint *) (sp + 3 * 8)) = (ptrint) ra;
390 *dontfillinexceptionstacktrace=true;
392 #if defined(USE_THREADS)
393 /* enter a monitor on the patching position */
395 builtin_monitorenter(o);
397 /* check if the position has already been patched */
400 builtin_monitorexit(o);
401 *dontfillinexceptionstacktrace=false;
406 /* get the classinfo */
408 if (!(c = helper_resolve_classinfo(cr))) {
409 *dontfillinexceptionstacktrace=false;
410 /*should here be an monitorexit too ?*/
414 *dontfillinexceptionstacktrace=false;
415 /*printf("ra:%p\n",ra);*/
416 if (!helper_initialize_class(beginJavaStack,c,ra+5)) return false;
418 /* patch back original code */
420 *((u8 *) (ra + 10)) = mcode;
422 /* patch the classinfo pointer */
424 *((ptrint *) (ra + 2)) = (ptrint) c;
426 /* if we show disassembly, we have to skip the nop's */
431 /* patch new function address */
433 *((ptrint *) (ra + 10 + 2)) = (ptrint) BUILTIN_new;
436 #if defined(USE_THREADS)
437 /* this position has been patched */
439 o->vftbl = (vftbl_t *) 1;
441 /* leave the monitor on the patching position */
442 *dontfillinexceptionstacktrace=true;
443 builtin_monitorexit(o);
444 *dontfillinexceptionstacktrace=false;
452 /* patcher_builtin_newarray ****************************************************
456 48 be 88 13 9b 00 00 00 00 00 mov $0x9b1388,%rsi
457 <patched call position>
458 48 b8 00 00 00 00 00 00 00 00 mov $0x0,%rax
461 *******************************************************************************/
463 bool patcher_builtin_newarray(u1 *sp)
466 java_objectheader *o;
468 constant_classref *cr;
471 /* get stuff from the stack */
473 ra = (u1 *) *((ptrint *) (sp + 3 * 8));
474 o = (java_objectheader *) *((ptrint *) (sp + 2 * 8));
475 mcode = *((u8 *) (sp + 1 * 8));
476 cr = (constant_classref *) *((ptrint *) (sp + 0 * 8));
478 /* calculate and set the new return address */
481 *((ptrint *) (sp + 3 * 8)) = (ptrint) ra;
483 *dontfillinexceptionstacktrace=true;
485 #if defined(USE_THREADS)
486 /* enter a monitor on the patching position */
488 builtin_monitorenter(o);
490 /* check if the position has already been patched */
493 builtin_monitorexit(o);
494 *dontfillinexceptionstacktrace=false;
499 /* get the classinfo */
501 if (!(c = helper_resolve_classinfo(cr))) {
502 *dontfillinexceptionstacktrace=false;
506 /* patch back original code */
508 *((u8 *) (ra + 10)) = mcode;
510 /* patch the class' vftbl pointer */
512 *((ptrint *) (ra + 2)) = (ptrint) c->vftbl;
514 /* if we show disassembly, we have to skip the nop's */
519 /* patch new function address */
521 *((ptrint *) (ra + 10 + 2)) = (ptrint) BUILTIN_newarray;
524 #if defined(USE_THREADS)
525 /* this position has been patched */
527 o->vftbl = (vftbl_t *) 1;
529 /* leave the monitor on the patching position */
531 builtin_monitorexit(o);
534 *dontfillinexceptionstacktrace=false;
540 /* patcher_builtin_multianewarray **********************************************
544 <patched call position>
545 48 bf 02 00 00 00 00 00 00 00 mov $0x2,%rdi
546 48 be 30 40 b2 00 00 00 00 00 mov $0xb24030,%rsi
547 48 89 e2 mov %rsp,%rdx
548 48 b8 7c 96 4b 00 00 00 00 00 mov $0x4b967c,%rax
551 *******************************************************************************/
553 bool patcher_builtin_multianewarray(u1 *sp)
556 java_objectheader *o;
558 constant_classref *cr;
561 /* get stuff from the stack */
563 ra = (u1 *) *((ptrint *) (sp + 3 * 8));
564 o = (java_objectheader *) *((ptrint *) (sp + 2 * 8));
565 mcode = *((u8 *) (sp + 1 * 8));
566 cr = (constant_classref *) *((ptrint *) (sp + 0 * 8));
568 /* calculate and set the new return address */
571 *((ptrint *) (sp + 3 * 8)) = (ptrint) ra;
573 *dontfillinexceptionstacktrace=true;
575 #if defined(USE_THREADS)
576 /* enter a monitor on the patching position */
578 builtin_monitorenter(o);
580 /* check if the position has already been patched */
583 builtin_monitorexit(o);
584 *dontfillinexceptionstacktrace=false;
589 /* get the classinfo */
591 if (!(c = helper_resolve_classinfo(cr))) {
592 *dontfillinexceptionstacktrace=false;
596 /* patch back original code */
598 *((u8 *) ra) = mcode;
600 /* if we show disassembly, we have to skip the nop's */
605 /* patch the class' vftbl pointer */
607 *((ptrint *) (ra + 10 + 2)) = (ptrint) c->vftbl;
609 /* patch new function address */
611 *((ptrint *) (ra + 10 + 10 + 3 + 2)) = (ptrint) BUILTIN_multianewarray;
614 #if defined(USE_THREADS)
615 /* this position has been patched */
617 o->vftbl = (vftbl_t *) 1;
619 /* leave the monitor on the patching position */
621 builtin_monitorexit(o);
623 *dontfillinexceptionstacktrace=false;
629 /* patcher_builtin_checkarraycast **********************************************
633 48 be b8 3f b2 00 00 00 00 00 mov $0xb23fb8,%rsi
634 <patched call position>
635 48 b8 00 00 00 00 00 00 00 00 mov $0x0,%rax
638 *******************************************************************************/
640 bool patcher_builtin_checkarraycast(u1 *sp)
643 java_objectheader *o;
645 constant_classref *cr;
648 /* get stuff from the stack */
650 ra = (u1 *) *((ptrint *) (sp + 3 * 8));
651 o = (java_objectheader *) *((ptrint *) (sp + 2 * 8));
652 mcode = *((u8 *) (sp + 1 * 8));
653 cr = (constant_classref *) *((ptrint *) (sp + 0 * 8));
655 /* calculate and set the new return address */
658 *((ptrint *) (sp + 3 * 8)) = (ptrint) ra;
660 *dontfillinexceptionstacktrace=true;
662 #if defined(USE_THREADS)
663 /* enter a monitor on the patching position */
665 builtin_monitorenter(o);
667 /* check if the position has already been patched */
670 builtin_monitorexit(o);
671 *dontfillinexceptionstacktrace=false;
676 /* get the classinfo */
678 if (!(c = helper_resolve_classinfo(cr))) {
679 *dontfillinexceptionstacktrace=false;
683 /* patch back original code */
685 *((u8 *) (ra + 10)) = mcode;
687 /* patch the class' vftbl pointer */
689 *((ptrint *) (ra + 2)) = (ptrint) c->vftbl;
691 /* if we show disassembly, we have to skip the nop's */
696 /* patch new function address */
698 *((ptrint *) (ra + 10 + 2)) = (ptrint) BUILTIN_checkarraycast;
701 #if defined(USE_THREADS)
702 /* this position has been patched */
704 o->vftbl = (vftbl_t *) 1;
706 /* leave the monitor on the patching position */
708 builtin_monitorexit(o);
710 *dontfillinexceptionstacktrace=false;
715 /* patcher_builtin_arrayinstanceof *********************************************
719 48 be 30 3c b2 00 00 00 00 00 mov $0xb23c30,%rsi
720 <patched call position>
721 48 b8 00 00 00 00 00 00 00 00 mov $0x0,%rax
724 *******************************************************************************/
726 bool patcher_builtin_arrayinstanceof(u1 *sp)
729 java_objectheader *o;
731 constant_classref *cr;
734 /* get stuff from the stack */
736 ra = (u1 *) *((ptrint *) (sp + 3 * 8));
737 o = (java_objectheader *) *((ptrint *) (sp + 2 * 8));
738 mcode = *((u8 *) (sp + 1 * 8));
739 cr = (constant_classref *) *((ptrint *) (sp + 0 * 8));
741 /* calculate and set the new return address */
744 *((ptrint *) (sp + 3 * 8)) = (ptrint) ra;
746 *dontfillinexceptionstacktrace=true;
748 #if defined(USE_THREADS)
749 /* enter a monitor on the patching position */
751 builtin_monitorenter(o);
753 /* check if the position has already been patched */
756 builtin_monitorexit(o);
762 /* get the classinfo */
764 if (!(c = helper_resolve_classinfo(cr))) {
765 *dontfillinexceptionstacktrace=false;
769 /* patch back original code */
771 *((u8 *) (ra + 10)) = mcode;
773 /* patch the class' vftbl pointer */
775 *((ptrint *) (ra + 2)) = (ptrint) c->vftbl;
777 /* if we show disassembly, we have to skip the nop's */
782 /* patch new function address */
784 *((ptrint *) (ra + 10 + 2)) = (ptrint) BUILTIN_arrayinstanceof;
787 #if defined(USE_THREADS)
788 /* this position has been patched */
790 o->vftbl = (vftbl_t *) 1;
792 /* leave the monitor on the patching position */
794 builtin_monitorexit(o);
796 *dontfillinexceptionstacktrace=false;
801 /* patcher_invokestatic_special ************************************************
805 *******************************************************************************/
807 bool patcher_invokestatic_special(u1 *sp)
810 java_objectheader *o;
812 unresolved_method *um;
815 /* get stuff from the stack */
817 ra = (u1 *) *((ptrint *) (sp + 3 * 8));
818 o = (java_objectheader *) *((ptrint *) (sp + 2 * 8));
819 mcode = *((u8 *) (sp + 1 * 8));
820 um = (unresolved_method *) *((ptrint *) (sp + 0 * 8));
822 /* calculate and set the new return address */
825 *((ptrint *) (sp + 3 * 8)) = (ptrint) ra;
827 *dontfillinexceptionstacktrace=true;
829 #if defined(USE_THREADS)
830 /* enter a monitor on the patching position */
832 builtin_monitorenter(o);
834 /* check if the position has already been patched */
837 builtin_monitorexit(o);
838 *dontfillinexceptionstacktrace=false;
843 /* get the fieldinfo */
845 if (!(m = helper_resolve_methodinfo(um))) {
846 *dontfillinexceptionstacktrace=false;
849 /* patch back original code */
851 *((u8 *) ra) = mcode;
853 /* if we show disassembly, we have to skip the nop's */
858 /* patch stubroutine */
860 *((ptrint *) (ra + 2)) = (ptrint) m->stubroutine;
863 #if defined(USE_THREADS)
864 /* this position has been patched */
866 o->vftbl = (vftbl_t *) 1;
868 /* leave the monitor on the patching position */
870 builtin_monitorexit(o);
872 *dontfillinexceptionstacktrace=false;
877 /* patcher_invokevirtual *******************************************************
881 *******************************************************************************/
883 bool patcher_invokevirtual(u1 *sp)
886 java_objectheader *o;
888 unresolved_method *um;
891 /* get stuff from the stack */
893 ra = (u1 *) *((ptrint *) (sp + 3 * 8));
894 o = (java_objectheader *) *((ptrint *) (sp + 2 * 8));
895 mcode = *((u8 *) (sp + 1 * 8));
896 um = (unresolved_method *) *((ptrint *) (sp + 0 * 8));
898 /* calculate and set the new return address */
901 *((ptrint *) (sp + 3 * 8)) = (ptrint) ra;
903 *dontfillinexceptionstacktrace=true;
905 #if defined(USE_THREADS)
906 /* enter a monitor on the patching position */
908 builtin_monitorenter(o);
910 /* check if the position has already been patched */
913 builtin_monitorexit(o);
914 *dontfillinexceptionstacktrace=false;
919 /* get the fieldinfo */
921 if (!(m = helper_resolve_methodinfo(um))) {
922 *dontfillinexceptionstacktrace=false;
926 /* patch back original code */
928 *((u8 *) ra) = mcode;
930 /* if we show disassembly, we have to skip the nop's */
935 /* patch vftbl index */
937 *((s4 *) (ra + 3 + 3)) = (s4) (OFFSET(vftbl_t, table[0]) +
938 sizeof(methodptr) * m->vftblindex);
941 #if defined(USE_THREADS)
942 /* this position has been patched */
944 o->vftbl = (vftbl_t *) 1;
946 /* leave the monitor on the patching position */
948 builtin_monitorexit(o);
950 *dontfillinexceptionstacktrace=false;
955 /* patcher_invokeinterface *****************************************************
959 *******************************************************************************/
961 bool patcher_invokeinterface(u1 *sp)
964 java_objectheader *o;
966 unresolved_method *um;
969 /* get stuff from the stack */
971 ra = (u1 *) *((ptrint *) (sp + 3 * 8));
972 o = (java_objectheader *) *((ptrint *) (sp + 2 * 8));
973 mcode = *((u8 *) (sp + 1 * 8));
974 um = (unresolved_method *) *((ptrint *) (sp + 0 * 8));
976 /* calculate and set the new return address */
979 *((ptrint *) (sp + 3 * 8)) = (ptrint) ra;
981 *dontfillinexceptionstacktrace=true;
983 #if defined(USE_THREADS)
984 /* enter a monitor on the patching position */
986 builtin_monitorenter(o);
988 /* check if the position has already been patched */
991 builtin_monitorexit(o);
992 *dontfillinexceptionstacktrace=true;
997 /* get the fieldinfo */
999 if (!(m = helper_resolve_methodinfo(um))) {
1000 *dontfillinexceptionstacktrace=false;
1004 /* patch back original code */
1006 *((u8 *) ra) = mcode;
1008 /* if we show disassembly, we have to skip the nop's */
1010 if (showdisassemble)
1013 /* patch interfacetable index */
1015 *((s4 *) (ra + 3 + 3)) = (s4) (OFFSET(vftbl_t, interfacetable[0]) -
1016 sizeof(methodptr) * m->class->index);
1018 /* patch method offset */
1020 *((s4 *) (ra + 3 + 7 + 3)) =
1021 (s4) (sizeof(methodptr) * (m - m->class->methods));
1024 #if defined(USE_THREADS)
1025 /* this position has been patched */
1027 o->vftbl = (vftbl_t *) 1;
1029 /* leave the monitor on the patching position */
1031 builtin_monitorexit(o);
1033 *dontfillinexceptionstacktrace=false;
1038 /* patcher_checkcast_instanceof_flags ******************************************
1042 *******************************************************************************/
1044 bool patcher_checkcast_instanceof_flags(u1 *sp)
1047 java_objectheader *o;
1049 constant_classref *cr;
1052 /* get stuff from the stack */
1054 ra = (u1 *) *((ptrint *) (sp + 3 * 8));
1055 o = (java_objectheader *) *((ptrint *) (sp + 2 * 8));
1056 mcode = *((u8 *) (sp + 1 * 8));
1057 cr = (constant_classref *) *((ptrint *) (sp + 0 * 8));
1059 /* calculate and set the new return address */
1062 *((ptrint *) (sp + 3 * 8)) = (ptrint) ra;
1064 *dontfillinexceptionstacktrace=true;
1066 #if defined(USE_THREADS)
1067 /* enter a monitor on the patching position */
1069 builtin_monitorenter(o);
1071 /* check if the position has already been patched */
1074 builtin_monitorexit(o);
1075 *dontfillinexceptionstacktrace=false;
1080 /* get the fieldinfo */
1082 if (!(c = helper_resolve_classinfo(cr))) {
1083 *dontfillinexceptionstacktrace=false;
1087 /* patch back original code */
1089 *((u8 *) ra) = mcode;
1091 /* if we show disassembly, we have to skip the nop's */
1093 if (showdisassemble)
1096 /* patch class flags */
1098 *((s4 *) (ra + 2)) = (s4) c->flags;
1101 #if defined(USE_THREADS)
1102 /* this position has been patched */
1104 o->vftbl = (vftbl_t *) 1;
1106 /* leave the monitor on the patching position */
1108 builtin_monitorexit(o);
1110 *dontfillinexceptionstacktrace=false;
1115 /* patcher_checkcast_instanceof_interface **************************************
1119 *******************************************************************************/
1121 bool patcher_checkcast_instanceof_interface(u1 *sp)
1124 java_objectheader *o;
1126 constant_classref *cr;
1129 /* get stuff from the stack */
1131 ra = (u1 *) *((ptrint *) (sp + 3 * 8));
1132 o = (java_objectheader *) *((ptrint *) (sp + 2 * 8));
1133 mcode = *((u8 *) (sp + 1 * 8));
1134 cr = (constant_classref *) *((ptrint *) (sp + 0 * 8));
1136 /* calculate and set the new return address */
1139 *((ptrint *) (sp + 3 * 8)) = (ptrint) ra;
1141 *dontfillinexceptionstacktrace=true;
1143 #if defined(USE_THREADS)
1144 /* enter a monitor on the patching position */
1146 builtin_monitorenter(o);
1148 /* check if the position has already been patched */
1151 builtin_monitorexit(o);
1152 *dontfillinexceptionstacktrace=false;
1157 /* get the fieldinfo */
1159 if (!(c = helper_resolve_classinfo(cr))) {
1160 *dontfillinexceptionstacktrace=false;
1164 /* patch back original code */
1166 *((u8 *) ra) = mcode;
1168 /* if we show disassembly, we have to skip the nop's */
1170 if (showdisassemble)
1173 /* patch super class index */
1175 *((s4 *) (ra + 7 + 3)) = (s4) c->index;
1177 *((s4 *) (ra + 7 + 7 + 3 + 6 + 3)) =
1178 (s4) (OFFSET(vftbl_t, interfacetable[0]) -
1179 c->index * sizeof(methodptr*));
1182 #if defined(USE_THREADS)
1183 /* this position has been patched */
1185 o->vftbl = (vftbl_t *) 1;
1187 /* leave the monitor on the patching position */
1189 builtin_monitorexit(o);
1191 *dontfillinexceptionstacktrace=false;
1196 /* patcher_checkcast_class *****************************************************
1200 *******************************************************************************/
1202 bool patcher_checkcast_class(u1 *sp)
1205 java_objectheader *o;
1207 constant_classref *cr;
1210 /* get stuff from the stack */
1212 ra = (u1 *) *((ptrint *) (sp + 3 * 8));
1213 o = (java_objectheader *) *((ptrint *) (sp + 2 * 8));
1214 mcode = *((u8 *) (sp + 1 * 8));
1215 cr = (constant_classref *) *((ptrint *) (sp + 0 * 8));
1217 /* calculate and set the new return address */
1220 *((ptrint *) (sp + 3 * 8)) = (ptrint) ra;
1222 *dontfillinexceptionstacktrace=true;
1224 #if defined(USE_THREADS)
1225 /* enter a monitor on the patching position */
1227 builtin_monitorenter(o);
1229 /* check if the position has already been patched */
1232 builtin_monitorexit(o);
1233 *dontfillinexceptionstacktrace=false;
1238 /* get the fieldinfo */
1240 if (!(c = helper_resolve_classinfo(cr))) {
1241 *dontfillinexceptionstacktrace=false;
1245 /* patch back original code */
1247 *((u8 *) ra) = mcode;
1249 /* if we show disassembly, we have to skip the nop's */
1251 if (showdisassemble)
1254 /* patch super class' vftbl */
1256 *((ptrint *) (ra + 2)) = (ptrint) c->vftbl;
1257 *((ptrint *) (ra + 10 + 7 + 7 + 3 + 2)) = (ptrint) c->vftbl;
1260 #if defined(USE_THREADS)
1261 /* this position has been patched */
1263 o->vftbl = (vftbl_t *) 1;
1265 /* leave the monitor on the patching position */
1267 builtin_monitorexit(o);
1269 *dontfillinexceptionstacktrace=false;
1274 /* patcher_instanceof_class ****************************************************
1278 *******************************************************************************/
1280 bool patcher_instanceof_class(u1 *sp)
1283 java_objectheader *o;
1285 constant_classref *cr;
1288 /* get stuff from the stack */
1290 ra = (u1 *) *((ptrint *) (sp + 3 * 8));
1291 o = (java_objectheader *) *((ptrint *) (sp + 2 * 8));
1292 mcode = *((u8 *) (sp + 1 * 8));
1293 cr = (constant_classref *) *((ptrint *) (sp + 0 * 8));
1295 /* calculate and set the new return address */
1298 *((ptrint *) (sp + 3 * 8)) = (ptrint) ra;
1300 *dontfillinexceptionstacktrace=true;
1302 #if defined(USE_THREADS)
1303 /* enter a monitor on the patching position */
1305 builtin_monitorenter(o);
1307 /* check if the position has already been patched */
1310 builtin_monitorexit(o);
1311 *dontfillinexceptionstacktrace=false;
1316 /* get the fieldinfo */
1318 if (!(c = helper_resolve_classinfo(cr))) {
1319 *dontfillinexceptionstacktrace=false;
1323 /* patch back original code */
1325 *((u8 *) ra) = mcode;
1327 /* if we show disassembly, we have to skip the nop's */
1329 if (showdisassemble)
1332 /* patch super class' vftbl */
1334 *((ptrint *) (ra + 2)) = (ptrint) c->vftbl;
1337 #if defined(USE_THREADS)
1338 /* this position has been patched */
1340 o->vftbl = (vftbl_t *) 1;
1342 /* leave the monitor on the patching position */
1344 builtin_monitorexit(o);
1346 *dontfillinexceptionstacktrace=false;
1351 /* patcher_clinit **************************************************************
1355 *******************************************************************************/
1357 bool patcher_clinit(u1 *sp)
1360 java_objectheader *o;
1363 void *beginJavaStack;
1365 /* get stuff from the stack */
1367 ra = (u1 *) *((ptrint *) (sp + 3 * 8));
1368 o = (java_objectheader *) *((ptrint *) (sp + 2 * 8));
1369 mcode = *((u8 *) (sp + 1 * 8));
1370 c = (classinfo *) *((ptrint *) (sp + 0 * 8));
1372 beginJavaStack = (void*) (sp + 3 * 8);
1374 /*printf("beginJavaStack: %p, ra %p\n",beginJavaStack,ra);*/
1375 /* calculate and set the new return address */
1378 *((ptrint *) (sp + 3 * 8)) = (ptrint) ra;
1380 #if defined(USE_THREADS)
1381 /* enter a monitor on the patching position */
1383 builtin_monitorenter(o);
1385 /* check if the position has already been patched */
1388 builtin_monitorexit(o);
1389 *dontfillinexceptionstacktrace=false;
1394 /* check if the class is initialized */
1395 *dontfillinexceptionstacktrace=false;
1396 if (!helper_initialize_class(beginJavaStack,c,ra)) return false;
1398 /* patch back original code */
1400 *((u8 *) ra) = mcode;
1402 #if defined(USE_THREADS)
1403 /* this position has been patched */
1405 o->vftbl = (vftbl_t *) 1;
1407 /* leave the monitor on the patching position */
1408 *dontfillinexceptionstacktrace=true;
1409 builtin_monitorexit(o);
1410 *dontfillinexceptionstacktrace=false;
1419 * These are local overrides for various environment variables in Emacs.
1420 * Please do not remove this and leave it at the end of the file, where
1421 * Emacs will automagically detect them.
1422 * ---------------------------------------------------------------------
1425 * indent-tabs-mode: t
1429 * vim:noexpandtab:sw=4:ts=4: