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 2956 2005-07-09 14:04:34Z twisti $
36 #include "vm/jit/x86_64/types.h"
38 #include "mm/memory.h"
39 #include "native/native.h"
40 #include "vm/builtin.h"
41 #include "vm/exceptions.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 4d 8b 15 86 fe ff ff mov -378(%rip),%r10
56 49 8b 32 mov (%r10),%rsi
58 *******************************************************************************/
60 bool patcher_get_putstatic(u1 *sp)
69 /* get stuff from the stack */
71 ra = (u1 *) *((ptrint *) (sp + 3 * 8));
72 o = (java_objectheader *) *((ptrint *) (sp + 2 * 8));
73 mcode = *((u8 *) (sp + 1 * 8));
74 uf = (unresolved_field *) *((ptrint *) (sp + 0 * 8));
76 /* calculate and set the new return address */
79 *((ptrint *) (sp + 3 * 8)) = (ptrint) ra;
83 /* get the fieldinfo */
85 if (!(fi = helper_resolve_fieldinfo(uf))) {
91 /* check if the field's class is initialized */
93 if (!initialize_class(fi->class)) {
99 /* patch back original code */
101 *((u8 *) ra) = mcode;
103 /* if we show disassembly, we have to skip the nop's */
105 if (opt_showdisassemble)
108 /* get RIP offset from machine instruction */
110 offset = *((u4 *) (ra + 3));
112 /* patch the field value's address (+ 7: is the size of the RIP move) */
114 *((ptrint *) (ra + 7 + offset)) = (ptrint) &(fi->value);
116 PATCHER_MARK_PATCHED_MONITOREXIT;
122 /* patcher_get_putfield ********************************************************
126 <patched call position>
127 45 8b 8f 00 00 00 00 mov 0x0(%r15),%r9d
129 *******************************************************************************/
131 bool patcher_get_putfield(u1 *sp)
134 java_objectheader *o;
136 unresolved_field *uf;
140 /* get stuff from the stack */
142 ra = (u1 *) *((ptrint *) (sp + 3 * 8));
143 o = (java_objectheader *) *((ptrint *) (sp + 2 * 8));
144 mcode = *((u8 *) (sp + 1 * 8));
145 uf = (unresolved_field *) *((ptrint *) (sp + 0 * 8));
147 /* calculate and set the new return address */
150 *((ptrint *) (sp + 3 * 8)) = (ptrint) ra;
152 PATCHER_MONITORENTER;
154 /* get the fieldinfo */
156 if (!(fi = helper_resolve_fieldinfo(uf))) {
162 /* patch back original code (instruction code is smaller than 8 bytes) */
164 *((u4 *) (ra + 0)) = (u4) mcode;
165 *((u1 *) (ra + 4)) = (u1) (mcode >> 32);
167 /* if we show disassembly, we have to skip the nop's */
169 if (opt_showdisassemble)
172 /* patch the field's offset: we check for the field type, because the */
173 /* instructions have different lengths */
175 if (IS_INT_LNG_TYPE(fi->type)) {
176 /* check for special case: %rsp or %r12 as base register */
181 *((u4 *) (ra + 4)) = (u4) (fi->offset);
183 *((u4 *) (ra + 3)) = (u4) (fi->offset);
186 /* check for special case: %rsp or %r12 as base register */
191 *((u4 *) (ra + 6)) = (u4) (fi->offset);
193 *((u4 *) (ra + 5)) = (u4) (fi->offset);
196 PATCHER_MARK_PATCHED_MONITOREXIT;
202 /* patcher_putfieldconst *******************************************************
206 <patched call position>
207 41 c7 85 00 00 00 00 7b 00 00 00 movl $0x7b,0x0(%r13)
209 *******************************************************************************/
211 bool patcher_putfieldconst(u1 *sp)
214 java_objectheader *o;
216 unresolved_field *uf;
219 /* get stuff from the stack */
221 ra = (u1 *) *((ptrint *) (sp + 3 * 8));
222 o = (java_objectheader *) *((ptrint *) (sp + 2 * 8));
223 mcode = *((u8 *) (sp + 1 * 8));
224 uf = (unresolved_field *) *((ptrint *) (sp + 0 * 8));
226 /* calculate and set the new return address */
229 *((ptrint *) (sp + 3 * 8)) = (ptrint) ra;
231 PATCHER_MONITORENTER;
233 /* get the fieldinfo */
235 if (!(fi = helper_resolve_fieldinfo(uf))) {
241 /* patch back original code */
243 *((u8 *) ra) = mcode;
245 /* if we show disassembly, we have to skip the nop's */
247 if (opt_showdisassemble)
250 /* patch the field's offset */
252 if (IS_2_WORD_TYPE(fi->type) || IS_ADR_TYPE(fi->type)) {
253 /* handle special case when the base register is %r12 */
255 if (*(ra + 2) == 0x84) {
256 *((u4 *) (ra + 4)) = (u4) (fi->offset);
257 *((u4 *) (ra + 12 + 4)) = (u4) (fi->offset + 4);
260 *((u4 *) (ra + 3)) = (u4) (fi->offset);
261 *((u4 *) (ra + 11 + 3)) = (u4) (fi->offset + 4);
265 /* handle special case when the base register is %r12 */
267 if (*(ra + 2) == 0x84)
268 *((u4 *) (ra + 4)) = (u4) (fi->offset);
270 *((u4 *) (ra + 3)) = (u4) (fi->offset);
273 PATCHER_MARK_PATCHED_MONITOREXIT;
279 /* patcher_builtin_new *********************************************************
283 48 bf a0 f0 92 00 00 00 00 00 mov $0x92f0a0,%rdi
284 <patched call position>
285 48 b8 00 00 00 00 00 00 00 00 mov $0x0,%rax
288 *******************************************************************************/
290 bool patcher_builtin_new(u1 *sp)
293 java_objectheader *o;
295 constant_classref *cr;
298 /* get stuff from the stack */
300 ra = (u1 *) *((ptrint *) (sp + 3 * 8));
301 o = (java_objectheader *) *((ptrint *) (sp + 2 * 8));
302 mcode = *((u8 *) (sp + 1 * 8));
303 cr = (constant_classref *) *((ptrint *) (sp + 0 * 8));
305 /* calculate and set the new return address */
308 *((ptrint *) (sp + 3 * 8)) = (ptrint) ra;
310 PATCHER_MONITORENTER;
312 /* get the classinfo */
314 if (!(c = helper_resolve_classinfo(cr))) {
320 if (!initialize_class(c)) {
326 /* patch back original code */
328 *((u8 *) (ra + 10)) = mcode;
330 /* patch the classinfo pointer */
332 *((ptrint *) (ra + 2)) = (ptrint) c;
334 /* if we show disassembly, we have to skip the nop's */
336 if (opt_showdisassemble)
339 /* patch new function address */
341 *((ptrint *) (ra + 10 + 2)) = (ptrint) BUILTIN_new;
343 PATCHER_MARK_PATCHED_MONITOREXIT;
349 /* patcher_builtin_newarray ****************************************************
353 48 be 88 13 9b 00 00 00 00 00 mov $0x9b1388,%rsi
354 <patched call position>
355 48 b8 00 00 00 00 00 00 00 00 mov $0x0,%rax
358 *******************************************************************************/
360 bool patcher_builtin_newarray(u1 *sp)
363 java_objectheader *o;
365 constant_classref *cr;
368 /* get stuff from the stack */
370 ra = (u1 *) *((ptrint *) (sp + 3 * 8));
371 o = (java_objectheader *) *((ptrint *) (sp + 2 * 8));
372 mcode = *((u8 *) (sp + 1 * 8));
373 cr = (constant_classref *) *((ptrint *) (sp + 0 * 8));
375 /* calculate and set the new return address */
378 *((ptrint *) (sp + 3 * 8)) = (ptrint) ra;
380 PATCHER_MONITORENTER;
382 /* get the classinfo */
384 if (!(c = helper_resolve_classinfo(cr))) {
390 /* patch back original code */
392 *((u8 *) (ra + 10)) = mcode;
394 /* patch the class' vftbl pointer */
396 *((ptrint *) (ra + 2)) = (ptrint) c->vftbl;
398 /* if we show disassembly, we have to skip the nop's */
400 if (opt_showdisassemble)
403 /* patch new function address */
405 *((ptrint *) (ra + 10 + 2)) = (ptrint) BUILTIN_newarray;
407 PATCHER_MARK_PATCHED_MONITOREXIT;
413 /* patcher_builtin_multianewarray **********************************************
417 <patched call position>
418 48 bf 02 00 00 00 00 00 00 00 mov $0x2,%rdi
419 48 be 30 40 b2 00 00 00 00 00 mov $0xb24030,%rsi
420 48 89 e2 mov %rsp,%rdx
421 48 b8 7c 96 4b 00 00 00 00 00 mov $0x4b967c,%rax
424 *******************************************************************************/
426 bool patcher_builtin_multianewarray(u1 *sp)
429 java_objectheader *o;
431 constant_classref *cr;
434 /* get stuff from the stack */
436 ra = (u1 *) *((ptrint *) (sp + 3 * 8));
437 o = (java_objectheader *) *((ptrint *) (sp + 2 * 8));
438 mcode = *((u8 *) (sp + 1 * 8));
439 cr = (constant_classref *) *((ptrint *) (sp + 0 * 8));
441 /* calculate and set the new return address */
444 *((ptrint *) (sp + 3 * 8)) = (ptrint) ra;
446 PATCHER_MONITORENTER;
448 /* get the classinfo */
450 if (!(c = helper_resolve_classinfo(cr))) {
456 /* patch back original code */
458 *((u8 *) ra) = mcode;
460 /* if we show disassembly, we have to skip the nop's */
462 if (opt_showdisassemble)
465 /* patch the class' vftbl pointer */
467 *((ptrint *) (ra + 10 + 2)) = (ptrint) c->vftbl;
469 /* patch new function address */
471 *((ptrint *) (ra + 10 + 10 + 3 + 2)) = (ptrint) BUILTIN_multianewarray;
473 PATCHER_MARK_PATCHED_MONITOREXIT;
479 /* patcher_builtin_arraycheckcast **********************************************
483 <patched call position>
484 48 be b8 3f b2 00 00 00 00 00 mov $0xb23fb8,%rsi
485 48 b8 00 00 00 00 00 00 00 00 mov $0x0,%rax
488 *******************************************************************************/
490 bool patcher_builtin_arraycheckcast(u1 *sp)
493 java_objectheader *o;
495 constant_classref *cr;
498 /* get stuff from the stack */
500 ra = (u1 *) *((ptrint *) (sp + 3 * 8));
501 o = (java_objectheader *) *((ptrint *) (sp + 2 * 8));
502 mcode = *((u8 *) (sp + 1 * 8));
503 cr = (constant_classref *) *((ptrint *) (sp + 0 * 8));
505 /* calculate and set the new return address */
508 *((ptrint *) (sp + 3 * 8)) = (ptrint) ra;
510 PATCHER_MONITORENTER;
512 /* get the classinfo */
514 if (!(c = helper_resolve_classinfo(cr))) {
520 /* patch back original code */
522 *((u8 *) ra) = mcode;
524 /* if we show disassembly, we have to skip the nop's */
526 if (opt_showdisassemble)
529 /* patch the class' vftbl pointer */
531 *((ptrint *) (ra + 2)) = (ptrint) c->vftbl;
533 /* patch new function address */
535 *((ptrint *) (ra + 10 + 2)) = (ptrint) BUILTIN_arraycheckcast;
537 PATCHER_MARK_PATCHED_MONITOREXIT;
543 /* patcher_builtin_arrayinstanceof *********************************************
547 48 be 30 3c b2 00 00 00 00 00 mov $0xb23c30,%rsi
548 <patched call position>
549 48 b8 00 00 00 00 00 00 00 00 mov $0x0,%rax
552 *******************************************************************************/
554 bool patcher_builtin_arrayinstanceof(u1 *sp)
557 java_objectheader *o;
559 constant_classref *cr;
562 /* get stuff from the stack */
564 ra = (u1 *) *((ptrint *) (sp + 3 * 8));
565 o = (java_objectheader *) *((ptrint *) (sp + 2 * 8));
566 mcode = *((u8 *) (sp + 1 * 8));
567 cr = (constant_classref *) *((ptrint *) (sp + 0 * 8));
569 /* calculate and set the new return address */
572 *((ptrint *) (sp + 3 * 8)) = (ptrint) ra;
574 PATCHER_MONITORENTER;
576 /* get the classinfo */
578 if (!(c = helper_resolve_classinfo(cr))) {
584 /* patch back original code */
586 *((u8 *) (ra + 10)) = mcode;
588 /* patch the class' vftbl pointer */
590 *((ptrint *) (ra + 2)) = (ptrint) c->vftbl;
592 /* if we show disassembly, we have to skip the nop's */
594 if (opt_showdisassemble)
597 /* patch new function address */
599 *((ptrint *) (ra + 10 + 2)) = (ptrint) BUILTIN_arrayinstanceof;
601 PATCHER_MARK_PATCHED_MONITOREXIT;
607 /* patcher_invokestatic_special ************************************************
611 <patched call position>
612 49 ba 00 00 00 00 00 00 00 00 mov $0x0,%r10
615 *******************************************************************************/
617 bool patcher_invokestatic_special(u1 *sp)
620 java_objectheader *o;
622 unresolved_method *um;
625 /* get stuff from the stack */
627 ra = (u1 *) *((ptrint *) (sp + 3 * 8));
628 o = (java_objectheader *) *((ptrint *) (sp + 2 * 8));
629 mcode = *((u8 *) (sp + 1 * 8));
630 um = (unresolved_method *) *((ptrint *) (sp + 0 * 8));
632 /* calculate and set the new return address */
635 *((ptrint *) (sp + 3 * 8)) = (ptrint) ra;
637 PATCHER_MONITORENTER;
639 /* get the fieldinfo */
641 if (!(m = helper_resolve_methodinfo(um))) {
646 /* patch back original code */
648 *((u8 *) ra) = mcode;
650 /* if we show disassembly, we have to skip the nop's */
652 if (opt_showdisassemble)
655 /* patch stubroutine */
657 *((ptrint *) (ra + 2)) = (ptrint) m->stubroutine;
659 PATCHER_MARK_PATCHED_MONITOREXIT;
665 /* patcher_invokevirtual *******************************************************
669 <patched call position>
670 4c 8b 17 mov (%rdi),%r10
671 49 8b 82 00 00 00 00 mov 0x0(%r10),%rax
674 *******************************************************************************/
676 bool patcher_invokevirtual(u1 *sp)
679 java_objectheader *o;
681 unresolved_method *um;
684 /* get stuff from the stack */
686 ra = (u1 *) *((ptrint *) (sp + 3 * 8));
687 o = (java_objectheader *) *((ptrint *) (sp + 2 * 8));
688 mcode = *((u8 *) (sp + 1 * 8));
689 um = (unresolved_method *) *((ptrint *) (sp + 0 * 8));
691 /* calculate and set the new return address */
694 *((ptrint *) (sp + 3 * 8)) = (ptrint) ra;
696 PATCHER_MONITORENTER;
698 /* get the fieldinfo */
700 if (!(m = helper_resolve_methodinfo(um))) {
706 /* patch back original code */
708 *((u8 *) ra) = mcode;
710 /* if we show disassembly, we have to skip the nop's */
712 if (opt_showdisassemble)
715 /* patch vftbl index */
717 *((s4 *) (ra + 3 + 3)) = (s4) (OFFSET(vftbl_t, table[0]) +
718 sizeof(methodptr) * m->vftblindex);
720 PATCHER_MARK_PATCHED_MONITOREXIT;
726 /* patcher_invokeinterface *****************************************************
730 <patched call position>
731 4c 8b 17 mov (%rdi),%r10
732 4d 8b 92 00 00 00 00 mov 0x0(%r10),%r10
733 49 8b 82 00 00 00 00 mov 0x0(%r10),%rax
736 *******************************************************************************/
738 bool patcher_invokeinterface(u1 *sp)
741 java_objectheader *o;
743 unresolved_method *um;
746 /* get stuff from the stack */
748 ra = (u1 *) *((ptrint *) (sp + 3 * 8));
749 o = (java_objectheader *) *((ptrint *) (sp + 2 * 8));
750 mcode = *((u8 *) (sp + 1 * 8));
751 um = (unresolved_method *) *((ptrint *) (sp + 0 * 8));
753 /* calculate and set the new return address */
756 *((ptrint *) (sp + 3 * 8)) = (ptrint) ra;
758 PATCHER_MONITORENTER;
760 /* get the fieldinfo */
762 if (!(m = helper_resolve_methodinfo(um))) {
768 /* patch back original code */
770 *((u8 *) ra) = mcode;
772 /* if we show disassembly, we have to skip the nop's */
774 if (opt_showdisassemble)
777 /* patch interfacetable index */
779 *((s4 *) (ra + 3 + 3)) = (s4) (OFFSET(vftbl_t, interfacetable[0]) -
780 sizeof(methodptr) * m->class->index);
782 /* patch method offset */
784 *((s4 *) (ra + 3 + 7 + 3)) =
785 (s4) (sizeof(methodptr) * (m - m->class->methods));
787 PATCHER_MARK_PATCHED_MONITOREXIT;
793 /* patcher_checkcast_instanceof_flags ******************************************
797 <patched call position>
798 41 ba 00 00 00 00 mov $0x0,%r10d
799 41 81 e2 00 02 00 00 and $0x200,%r10d
800 0f 84 35 00 00 00 je 0x00002aaaaab01479
802 *******************************************************************************/
804 bool patcher_checkcast_instanceof_flags(u1 *sp)
807 java_objectheader *o;
809 constant_classref *cr;
812 /* get stuff from the stack */
814 ra = (u1 *) *((ptrint *) (sp + 3 * 8));
815 o = (java_objectheader *) *((ptrint *) (sp + 2 * 8));
816 mcode = *((u8 *) (sp + 1 * 8));
817 cr = (constant_classref *) *((ptrint *) (sp + 0 * 8));
819 /* calculate and set the new return address */
822 *((ptrint *) (sp + 3 * 8)) = (ptrint) ra;
824 PATCHER_MONITORENTER;
826 /* get the fieldinfo */
828 if (!(c = helper_resolve_classinfo(cr))) {
834 /* patch back original code */
836 *((u8 *) ra) = mcode;
838 /* if we show disassembly, we have to skip the nop's */
840 if (opt_showdisassemble)
843 /* patch class flags */
845 *((s4 *) (ra + 2)) = (s4) c->flags;
847 PATCHER_MARK_PATCHED_MONITOREXIT;
853 /* patcher_checkcast_instanceof_interface **************************************
857 <patched call position>
858 45 8b 9a 1c 00 00 00 mov 0x1c(%r10),%r11d
859 49 81 eb 00 00 00 00 sub $0x0,%r11
860 4d 85 db test %r11,%r11
861 0f 8e 94 04 00 00 jle 0x00002aaaaab018f8
862 4d 8b 9a 00 00 00 00 mov 0x0(%r10),%r11
864 *******************************************************************************/
866 bool patcher_checkcast_instanceof_interface(u1 *sp)
869 java_objectheader *o;
871 constant_classref *cr;
874 /* get stuff from the stack */
876 ra = (u1 *) *((ptrint *) (sp + 3 * 8));
877 o = (java_objectheader *) *((ptrint *) (sp + 2 * 8));
878 mcode = *((u8 *) (sp + 1 * 8));
879 cr = (constant_classref *) *((ptrint *) (sp + 0 * 8));
881 /* calculate and set the new return address */
884 *((ptrint *) (sp + 3 * 8)) = (ptrint) ra;
886 PATCHER_MONITORENTER;
888 /* get the fieldinfo */
890 if (!(c = helper_resolve_classinfo(cr))) {
896 /* patch back original code */
898 *((u8 *) ra) = mcode;
900 /* if we show disassembly, we have to skip the nop's */
902 if (opt_showdisassemble)
905 /* patch super class index */
907 *((s4 *) (ra + 7 + 3)) = (s4) c->index;
909 *((s4 *) (ra + 7 + 7 + 3 + 6 + 3)) =
910 (s4) (OFFSET(vftbl_t, interfacetable[0]) -
911 c->index * sizeof(methodptr*));
913 PATCHER_MARK_PATCHED_MONITOREXIT;
919 /* patcher_checkcast_class *****************************************************
923 <patched call position>
924 49 bb 00 00 00 00 00 00 00 00 mov $0x0,%r11
925 45 8b 92 20 00 00 00 mov 0x20(%r10),%r10d
926 45 8b 9b 20 00 00 00 mov 0x20(%r11),%r11d
927 4d 29 da sub %r11,%r10
928 49 bb 00 00 00 00 00 00 00 00 mov $0x0,%r11
930 *******************************************************************************/
932 bool patcher_checkcast_class(u1 *sp)
935 java_objectheader *o;
937 constant_classref *cr;
940 /* get stuff from the stack */
942 ra = (u1 *) *((ptrint *) (sp + 3 * 8));
943 o = (java_objectheader *) *((ptrint *) (sp + 2 * 8));
944 mcode = *((u8 *) (sp + 1 * 8));
945 cr = (constant_classref *) *((ptrint *) (sp + 0 * 8));
947 /* calculate and set the new return address */
950 *((ptrint *) (sp + 3 * 8)) = (ptrint) ra;
952 PATCHER_MONITORENTER;
954 /* get the fieldinfo */
956 if (!(c = helper_resolve_classinfo(cr))) {
962 /* patch back original code */
964 *((u8 *) ra) = mcode;
966 /* if we show disassembly, we have to skip the nop's */
968 if (opt_showdisassemble)
971 /* patch super class' vftbl */
973 *((ptrint *) (ra + 2)) = (ptrint) c->vftbl;
974 *((ptrint *) (ra + 10 + 7 + 7 + 3 + 2)) = (ptrint) c->vftbl;
976 PATCHER_MARK_PATCHED_MONITOREXIT;
982 /* patcher_instanceof_class ****************************************************
986 <patched call position>
987 49 ba 00 00 00 00 00 00 00 00 mov $0x0,%r10
989 *******************************************************************************/
991 bool patcher_instanceof_class(u1 *sp)
994 java_objectheader *o;
996 constant_classref *cr;
999 /* get stuff from the stack */
1001 ra = (u1 *) *((ptrint *) (sp + 3 * 8));
1002 o = (java_objectheader *) *((ptrint *) (sp + 2 * 8));
1003 mcode = *((u8 *) (sp + 1 * 8));
1004 cr = (constant_classref *) *((ptrint *) (sp + 0 * 8));
1006 /* calculate and set the new return address */
1009 *((ptrint *) (sp + 3 * 8)) = (ptrint) ra;
1011 PATCHER_MONITORENTER;
1013 /* get the fieldinfo */
1015 if (!(c = helper_resolve_classinfo(cr))) {
1016 PATCHER_MONITOREXIT;
1021 /* patch back original code */
1023 *((u8 *) ra) = mcode;
1025 /* if we show disassembly, we have to skip the nop's */
1027 if (opt_showdisassemble)
1030 /* patch super class' vftbl */
1032 *((ptrint *) (ra + 2)) = (ptrint) c->vftbl;
1034 PATCHER_MARK_PATCHED_MONITOREXIT;
1040 /* patcher_clinit **************************************************************
1042 May be used for GET/PUTSTATIC and in native stub.
1046 <patched call position>
1047 4d 8b 15 92 ff ff ff mov -110(%rip),%r10
1048 49 89 1a mov %rbx,(%r10)
1050 *******************************************************************************/
1052 bool patcher_clinit(u1 *sp)
1055 java_objectheader *o;
1059 /* get stuff from the stack */
1061 ra = (u1 *) *((ptrint *) (sp + 3 * 8));
1062 o = (java_objectheader *) *((ptrint *) (sp + 2 * 8));
1063 mcode = *((u8 *) (sp + 1 * 8));
1064 c = (classinfo *) *((ptrint *) (sp + 0 * 8));
1066 /* calculate and set the new return address */
1069 *((ptrint *) (sp + 3 * 8)) = (ptrint) ra;
1071 PATCHER_MONITORENTER;
1073 /* check if the class is initialized */
1075 if (!initialize_class(c)) {
1076 PATCHER_MONITOREXIT;
1081 /* patch back original code */
1083 *((u8 *) ra) = mcode;
1085 PATCHER_MARK_PATCHED_MONITOREXIT;
1091 /* patcher_resolve_native ******************************************************
1095 <patched call position>
1096 48 b8 00 00 00 00 00 00 00 00 mov $0x0,%rax
1097 48 ff d0 callq *%rax
1099 *******************************************************************************/
1101 #if !defined(ENABLE_STATICVM)
1102 bool patcher_resolve_native(u1 *sp)
1105 java_objectheader *o;
1110 /* get stuff from the stack */
1112 ra = (u1 *) *((ptrint *) (sp + 3 * 8));
1113 o = (java_objectheader *) *((ptrint *) (sp + 2 * 8));
1114 mcode = *((u8 *) (sp + 1 * 8));
1115 m = (methodinfo *) *((ptrint *) (sp + 0 * 8));
1117 /* calculate and set the new return address */
1120 *((ptrint *) (sp + 3 * 8)) = (ptrint) ra;
1122 PATCHER_MONITORENTER;
1124 /* resolve native function */
1126 if (!(f = native_resolve_function(m))) {
1127 PATCHER_MONITOREXIT;
1132 /* patch back original code */
1134 *((u8 *) ra) = mcode;
1136 /* if we show disassembly, we have to skip the nop's */
1138 if (opt_showdisassemble)
1141 /* patch native function pointer */
1143 *((ptrint *) (ra + 2)) = (ptrint) f;
1145 PATCHER_MARK_PATCHED_MONITOREXIT;
1149 #endif /* !defined(ENABLE_STATICVM) */
1153 * These are local overrides for various environment variables in Emacs.
1154 * Please do not remove this and leave it at the end of the file, where
1155 * Emacs will automagically detect them.
1156 * ---------------------------------------------------------------------
1159 * indent-tabs-mode: t
1163 * vim:noexpandtab:sw=4:ts=4: