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 3353 2005-10-05 13:30:10Z edwin $
39 #include "mm/memory.h"
40 #include "native/native.h"
41 #include "vm/builtin.h"
42 #include "vm/exceptions.h"
44 #include "vm/initialize.h"
45 #include "vm/options.h"
46 #include "vm/references.h"
47 #include "vm/jit/helper.h"
48 #include "vm/jit/patcher.h"
51 /* patcher_get_putstatic *******************************************************
55 <patched call position>
56 4d 8b 15 86 fe ff ff mov -378(%rip),%r10
57 49 8b 32 mov (%r10),%rsi
59 *******************************************************************************/
61 bool patcher_get_putstatic(u1 *sp)
71 /* get stuff from the stack */
73 ra = (u1 *) *((ptrint *) (sp + 4 * 8));
74 o = (java_objectheader *) *((ptrint *) (sp + 3 * 8));
75 mcode = *((u8 *) (sp + 2 * 8));
76 uf = (unresolved_field *) *((ptrint *) (sp + 1 * 8));
77 disp = *((s4 *) (sp + 0 * 8));
79 /* calculate and set the new return address */
82 *((ptrint *) (sp + 4 * 8)) = (ptrint) ra;
86 /* get the fieldinfo */
88 if (!(fi = helper_resolve_fieldinfo(uf))) {
94 /* check if the field's class is initialized */
96 if (!initialize_class(fi->class)) {
102 /* patch back original code */
104 *((u8 *) ra) = mcode;
106 /* if we show disassembly, we have to skip the nop's */
108 if (opt_showdisassemble)
111 /* get RIP offset from machine instruction */
113 offset = *((u4 *) (ra + 3));
115 /* patch the field value's address (+ 7: is the size of the RIP move) */
117 *((ptrint *) (ra + 7 + offset)) = (ptrint) &(fi->value);
119 PATCHER_MARK_PATCHED_MONITOREXIT;
125 /* patcher_get_putfield ********************************************************
129 <patched call position>
130 45 8b 8f 00 00 00 00 mov 0x0(%r15),%r9d
132 *******************************************************************************/
134 bool patcher_get_putfield(u1 *sp)
137 java_objectheader *o;
139 unresolved_field *uf;
143 /* get stuff from the stack */
145 ra = (u1 *) *((ptrint *) (sp + 4 * 8));
146 o = (java_objectheader *) *((ptrint *) (sp + 3 * 8));
147 mcode = *((u8 *) (sp + 2 * 8));
148 uf = (unresolved_field *) *((ptrint *) (sp + 1 * 8));
150 /* calculate and set the new return address */
153 *((ptrint *) (sp + 4 * 8)) = (ptrint) ra;
155 PATCHER_MONITORENTER;
157 /* get the fieldinfo */
159 if (!(fi = helper_resolve_fieldinfo(uf))) {
165 /* patch back original code (instruction code is smaller than 8 bytes) */
167 *((u4 *) (ra + 0)) = (u4) mcode;
168 *((u1 *) (ra + 4)) = (u1) (mcode >> 32);
170 /* if we show disassembly, we have to skip the nop's */
172 if (opt_showdisassemble)
175 /* patch the field's offset: we check for the field type, because the */
176 /* instructions have different lengths */
178 if (IS_INT_LNG_TYPE(fi->type)) {
179 /* check for special case: %rsp or %r12 as base register */
184 *((u4 *) (ra + 4)) = (u4) (fi->offset);
186 *((u4 *) (ra + 3)) = (u4) (fi->offset);
189 /* check for special case: %rsp or %r12 as base register */
194 *((u4 *) (ra + 6)) = (u4) (fi->offset);
196 *((u4 *) (ra + 5)) = (u4) (fi->offset);
199 PATCHER_MARK_PATCHED_MONITOREXIT;
205 /* patcher_putfieldconst *******************************************************
209 <patched call position>
210 41 c7 85 00 00 00 00 7b 00 00 00 movl $0x7b,0x0(%r13)
212 *******************************************************************************/
214 bool patcher_putfieldconst(u1 *sp)
217 java_objectheader *o;
219 unresolved_field *uf;
222 /* get stuff from the stack */
224 ra = (u1 *) *((ptrint *) (sp + 4 * 8));
225 o = (java_objectheader *) *((ptrint *) (sp + 3 * 8));
226 mcode = *((u8 *) (sp + 2 * 8));
227 uf = (unresolved_field *) *((ptrint *) (sp + 1 * 8));
229 /* calculate and set the new return address */
232 *((ptrint *) (sp + 4 * 8)) = (ptrint) ra;
234 PATCHER_MONITORENTER;
236 /* get the fieldinfo */
238 if (!(fi = helper_resolve_fieldinfo(uf))) {
244 /* patch back original code */
246 *((u8 *) ra) = mcode;
248 /* if we show disassembly, we have to skip the nop's */
250 if (opt_showdisassemble)
253 /* patch the field's offset */
255 if (IS_2_WORD_TYPE(fi->type) || IS_ADR_TYPE(fi->type)) {
256 /* handle special case when the base register is %r12 */
258 if (*(ra + 2) == 0x84) {
259 *((u4 *) (ra + 4)) = (u4) (fi->offset);
260 *((u4 *) (ra + 12 + 4)) = (u4) (fi->offset + 4);
263 *((u4 *) (ra + 3)) = (u4) (fi->offset);
264 *((u4 *) (ra + 11 + 3)) = (u4) (fi->offset + 4);
268 /* handle special case when the base register is %r12 */
270 if (*(ra + 2) == 0x84)
271 *((u4 *) (ra + 4)) = (u4) (fi->offset);
273 *((u4 *) (ra + 3)) = (u4) (fi->offset);
276 PATCHER_MARK_PATCHED_MONITOREXIT;
282 /* patcher_builtin_new *********************************************************
286 48 bf a0 f0 92 00 00 00 00 00 mov $0x92f0a0,%rdi
287 <patched call position>
288 48 b8 00 00 00 00 00 00 00 00 mov $0x0,%rax
291 *******************************************************************************/
293 bool patcher_builtin_new(u1 *sp)
296 java_objectheader *o;
298 constant_classref *cr;
301 /* get stuff from the stack */
303 ra = (u1 *) *((ptrint *) (sp + 4 * 8));
304 o = (java_objectheader *) *((ptrint *) (sp + 3 * 8));
305 mcode = *((u8 *) (sp + 2 * 8));
306 cr = (constant_classref *) *((ptrint *) (sp + 1 * 8));
308 /* calculate and set the new return address */
311 *((ptrint *) (sp + 4 * 8)) = (ptrint) ra;
313 PATCHER_MONITORENTER;
315 /* get the classinfo */
317 if (!(c = helper_resolve_classinfo_nonabstract(cr))) {
323 if (!initialize_class(c)) {
329 /* patch back original code */
331 *((u8 *) (ra + 10)) = mcode;
333 /* patch the classinfo pointer */
335 *((ptrint *) (ra + 2)) = (ptrint) c;
337 /* if we show disassembly, we have to skip the nop's */
339 if (opt_showdisassemble)
342 /* patch new function address */
344 *((ptrint *) (ra + 10 + 2)) = (ptrint) BUILTIN_new;
346 PATCHER_MARK_PATCHED_MONITOREXIT;
352 /* patcher_builtin_newarray ****************************************************
356 48 be 88 13 9b 00 00 00 00 00 mov $0x9b1388,%rsi
357 <patched call position>
358 48 b8 00 00 00 00 00 00 00 00 mov $0x0,%rax
361 *******************************************************************************/
363 bool patcher_builtin_newarray(u1 *sp)
366 java_objectheader *o;
368 constant_classref *cr;
371 /* get stuff from the stack */
373 ra = (u1 *) *((ptrint *) (sp + 4 * 8));
374 o = (java_objectheader *) *((ptrint *) (sp + 3 * 8));
375 mcode = *((u8 *) (sp + 2 * 8));
376 cr = (constant_classref *) *((ptrint *) (sp + 1 * 8));
378 /* calculate and set the new return address */
381 *((ptrint *) (sp + 4 * 8)) = (ptrint) ra;
383 PATCHER_MONITORENTER;
385 /* get the classinfo */
387 if (!(c = helper_resolve_classinfo(cr))) {
393 /* patch back original code */
395 *((u8 *) (ra + 10)) = mcode;
397 /* patch the class' vftbl pointer */
399 *((ptrint *) (ra + 2)) = (ptrint) c->vftbl;
401 /* if we show disassembly, we have to skip the nop's */
403 if (opt_showdisassemble)
406 /* patch new function address */
408 *((ptrint *) (ra + 10 + 2)) = (ptrint) BUILTIN_newarray;
410 PATCHER_MARK_PATCHED_MONITOREXIT;
416 /* patcher_builtin_multianewarray **********************************************
420 <patched call position>
421 48 bf 02 00 00 00 00 00 00 00 mov $0x2,%rdi
422 48 be 30 40 b2 00 00 00 00 00 mov $0xb24030,%rsi
423 48 89 e2 mov %rsp,%rdx
424 48 b8 7c 96 4b 00 00 00 00 00 mov $0x4b967c,%rax
427 *******************************************************************************/
429 bool patcher_builtin_multianewarray(u1 *sp)
432 java_objectheader *o;
434 constant_classref *cr;
437 /* get stuff from the stack */
439 ra = (u1 *) *((ptrint *) (sp + 4 * 8));
440 o = (java_objectheader *) *((ptrint *) (sp + 3 * 8));
441 mcode = *((u8 *) (sp + 2 * 8));
442 cr = (constant_classref *) *((ptrint *) (sp + 1 * 8));
444 /* calculate and set the new return address */
447 *((ptrint *) (sp + 4 * 8)) = (ptrint) ra;
449 PATCHER_MONITORENTER;
451 /* get the classinfo */
453 if (!(c = helper_resolve_classinfo(cr))) {
459 /* patch back original code */
461 *((u8 *) ra) = mcode;
463 /* if we show disassembly, we have to skip the nop's */
465 if (opt_showdisassemble)
468 /* patch the class' vftbl pointer */
470 *((ptrint *) (ra + 10 + 2)) = (ptrint) c->vftbl;
472 /* patch new function address */
474 *((ptrint *) (ra + 10 + 10 + 3 + 2)) = (ptrint) BUILTIN_multianewarray;
476 PATCHER_MARK_PATCHED_MONITOREXIT;
482 /* patcher_builtin_arraycheckcast **********************************************
486 <patched call position>
487 48 be b8 3f b2 00 00 00 00 00 mov $0xb23fb8,%rsi
488 48 b8 00 00 00 00 00 00 00 00 mov $0x0,%rax
491 *******************************************************************************/
493 bool patcher_builtin_arraycheckcast(u1 *sp)
496 java_objectheader *o;
498 constant_classref *cr;
501 /* get stuff from the stack */
503 ra = (u1 *) *((ptrint *) (sp + 4 * 8));
504 o = (java_objectheader *) *((ptrint *) (sp + 3 * 8));
505 mcode = *((u8 *) (sp + 2 * 8));
506 cr = (constant_classref *) *((ptrint *) (sp + 1 * 8));
508 /* calculate and set the new return address */
511 *((ptrint *) (sp + 4 * 8)) = (ptrint) ra;
513 PATCHER_MONITORENTER;
515 /* get the classinfo */
517 if (!(c = helper_resolve_classinfo(cr))) {
523 /* patch back original code */
525 *((u8 *) ra) = mcode;
527 /* if we show disassembly, we have to skip the nop's */
529 if (opt_showdisassemble)
532 /* patch the class' vftbl pointer */
534 *((ptrint *) (ra + 2)) = (ptrint) c->vftbl;
536 /* patch new function address */
538 *((ptrint *) (ra + 10 + 2)) = (ptrint) BUILTIN_arraycheckcast;
540 PATCHER_MARK_PATCHED_MONITOREXIT;
546 /* patcher_builtin_arrayinstanceof *********************************************
550 48 be 30 3c b2 00 00 00 00 00 mov $0xb23c30,%rsi
551 <patched call position>
552 48 b8 00 00 00 00 00 00 00 00 mov $0x0,%rax
555 *******************************************************************************/
557 bool patcher_builtin_arrayinstanceof(u1 *sp)
560 java_objectheader *o;
562 constant_classref *cr;
565 /* get stuff from the stack */
567 ra = (u1 *) *((ptrint *) (sp + 4 * 8));
568 o = (java_objectheader *) *((ptrint *) (sp + 3 * 8));
569 mcode = *((u8 *) (sp + 2 * 8));
570 cr = (constant_classref *) *((ptrint *) (sp + 1 * 8));
572 /* calculate and set the new return address */
575 *((ptrint *) (sp + 4 * 8)) = (ptrint) ra;
577 PATCHER_MONITORENTER;
579 /* get the classinfo */
581 if (!(c = helper_resolve_classinfo(cr))) {
587 /* patch back original code */
589 *((u8 *) (ra + 10)) = mcode;
591 /* patch the class' vftbl pointer */
593 *((ptrint *) (ra + 2)) = (ptrint) c->vftbl;
595 /* if we show disassembly, we have to skip the nop's */
597 if (opt_showdisassemble)
600 /* patch new function address */
602 *((ptrint *) (ra + 10 + 2)) = (ptrint) BUILTIN_arrayinstanceof;
604 PATCHER_MARK_PATCHED_MONITOREXIT;
610 /* patcher_invokestatic_special ************************************************
614 <patched call position>
615 49 ba 00 00 00 00 00 00 00 00 mov $0x0,%r10
618 *******************************************************************************/
620 bool patcher_invokestatic_special(u1 *sp)
623 java_objectheader *o;
625 unresolved_method *um;
628 /* get stuff from the stack */
630 ra = (u1 *) *((ptrint *) (sp + 4 * 8));
631 o = (java_objectheader *) *((ptrint *) (sp + 3 * 8));
632 mcode = *((u8 *) (sp + 2 * 8));
633 um = (unresolved_method *) *((ptrint *) (sp + 1 * 8));
635 /* calculate and set the new return address */
638 *((ptrint *) (sp + 4 * 8)) = (ptrint) ra;
640 PATCHER_MONITORENTER;
642 /* get the fieldinfo */
644 if (!(m = helper_resolve_methodinfo(um))) {
649 /* patch back original code */
651 *((u8 *) ra) = mcode;
653 /* if we show disassembly, we have to skip the nop's */
655 if (opt_showdisassemble)
658 /* patch stubroutine */
660 *((ptrint *) (ra + 2)) = (ptrint) m->stubroutine;
662 PATCHER_MARK_PATCHED_MONITOREXIT;
668 /* patcher_invokevirtual *******************************************************
672 <patched call position>
673 4c 8b 17 mov (%rdi),%r10
674 49 8b 82 00 00 00 00 mov 0x0(%r10),%rax
677 *******************************************************************************/
679 bool patcher_invokevirtual(u1 *sp)
682 java_objectheader *o;
684 unresolved_method *um;
687 /* get stuff from the stack */
689 ra = (u1 *) *((ptrint *) (sp + 4 * 8));
690 o = (java_objectheader *) *((ptrint *) (sp + 3 * 8));
691 mcode = *((u8 *) (sp + 2 * 8));
692 um = (unresolved_method *) *((ptrint *) (sp + 1 * 8));
694 /* calculate and set the new return address */
697 *((ptrint *) (sp + 4 * 8)) = (ptrint) ra;
699 PATCHER_MONITORENTER;
701 /* get the fieldinfo */
703 if (!(m = helper_resolve_methodinfo(um))) {
709 /* patch back original code */
711 *((u8 *) ra) = mcode;
713 /* if we show disassembly, we have to skip the nop's */
715 if (opt_showdisassemble)
718 /* patch vftbl index */
720 *((s4 *) (ra + 3 + 3)) = (s4) (OFFSET(vftbl_t, table[0]) +
721 sizeof(methodptr) * m->vftblindex);
723 PATCHER_MARK_PATCHED_MONITOREXIT;
729 /* patcher_invokeinterface *****************************************************
733 <patched call position>
734 4c 8b 17 mov (%rdi),%r10
735 4d 8b 92 00 00 00 00 mov 0x0(%r10),%r10
736 49 8b 82 00 00 00 00 mov 0x0(%r10),%rax
739 *******************************************************************************/
741 bool patcher_invokeinterface(u1 *sp)
744 java_objectheader *o;
746 unresolved_method *um;
749 /* get stuff from the stack */
751 ra = (u1 *) *((ptrint *) (sp + 4 * 8));
752 o = (java_objectheader *) *((ptrint *) (sp + 3 * 8));
753 mcode = *((u8 *) (sp + 2 * 8));
754 um = (unresolved_method *) *((ptrint *) (sp + 1 * 8));
756 /* calculate and set the new return address */
759 *((ptrint *) (sp + 4 * 8)) = (ptrint) ra;
761 PATCHER_MONITORENTER;
763 /* get the fieldinfo */
765 if (!(m = helper_resolve_methodinfo(um))) {
771 /* patch back original code */
773 *((u8 *) ra) = mcode;
775 /* if we show disassembly, we have to skip the nop's */
777 if (opt_showdisassemble)
780 /* patch interfacetable index */
782 *((s4 *) (ra + 3 + 3)) = (s4) (OFFSET(vftbl_t, interfacetable[0]) -
783 sizeof(methodptr) * m->class->index);
785 /* patch method offset */
787 *((s4 *) (ra + 3 + 7 + 3)) =
788 (s4) (sizeof(methodptr) * (m - m->class->methods));
790 PATCHER_MARK_PATCHED_MONITOREXIT;
796 /* patcher_checkcast_instanceof_flags ******************************************
800 <patched call position>
801 41 ba 00 00 00 00 mov $0x0,%r10d
802 41 81 e2 00 02 00 00 and $0x200,%r10d
803 0f 84 35 00 00 00 je 0x00002aaaaab01479
805 *******************************************************************************/
807 bool patcher_checkcast_instanceof_flags(u1 *sp)
810 java_objectheader *o;
812 constant_classref *cr;
815 /* get stuff from the stack */
817 ra = (u1 *) *((ptrint *) (sp + 4 * 8));
818 o = (java_objectheader *) *((ptrint *) (sp + 3 * 8));
819 mcode = *((u8 *) (sp + 2 * 8));
820 cr = (constant_classref *) *((ptrint *) (sp + 1 * 8));
822 /* calculate and set the new return address */
825 *((ptrint *) (sp + 4 * 8)) = (ptrint) ra;
827 PATCHER_MONITORENTER;
829 /* get the fieldinfo */
831 if (!(c = helper_resolve_classinfo(cr))) {
837 /* patch back original code */
839 *((u8 *) ra) = mcode;
841 /* if we show disassembly, we have to skip the nop's */
843 if (opt_showdisassemble)
846 /* patch class flags */
848 *((s4 *) (ra + 2)) = (s4) c->flags;
850 PATCHER_MARK_PATCHED_MONITOREXIT;
856 /* patcher_checkcast_instanceof_interface **************************************
860 <patched call position>
861 45 8b 9a 1c 00 00 00 mov 0x1c(%r10),%r11d
862 49 81 eb 00 00 00 00 sub $0x0,%r11
863 4d 85 db test %r11,%r11
864 0f 8e 94 04 00 00 jle 0x00002aaaaab018f8
865 4d 8b 9a 00 00 00 00 mov 0x0(%r10),%r11
867 *******************************************************************************/
869 bool patcher_checkcast_instanceof_interface(u1 *sp)
872 java_objectheader *o;
874 constant_classref *cr;
877 /* get stuff from the stack */
879 ra = (u1 *) *((ptrint *) (sp + 4 * 8));
880 o = (java_objectheader *) *((ptrint *) (sp + 3 * 8));
881 mcode = *((u8 *) (sp + 2 * 8));
882 cr = (constant_classref *) *((ptrint *) (sp + 1 * 8));
884 /* calculate and set the new return address */
887 *((ptrint *) (sp + 4 * 8)) = (ptrint) ra;
889 PATCHER_MONITORENTER;
891 /* get the fieldinfo */
893 if (!(c = helper_resolve_classinfo(cr))) {
899 /* patch back original code */
901 *((u8 *) ra) = mcode;
903 /* if we show disassembly, we have to skip the nop's */
905 if (opt_showdisassemble)
908 /* patch super class index */
910 *((s4 *) (ra + 7 + 3)) = (s4) c->index;
912 *((s4 *) (ra + 7 + 7 + 3 + 6 + 3)) =
913 (s4) (OFFSET(vftbl_t, interfacetable[0]) -
914 c->index * sizeof(methodptr*));
916 PATCHER_MARK_PATCHED_MONITOREXIT;
922 /* patcher_checkcast_class *****************************************************
926 <patched call position>
927 49 bb 00 00 00 00 00 00 00 00 mov $0x0,%r11
928 45 8b 92 20 00 00 00 mov 0x20(%r10),%r10d
929 45 8b 9b 20 00 00 00 mov 0x20(%r11),%r11d
930 4d 29 da sub %r11,%r10
931 49 bb 00 00 00 00 00 00 00 00 mov $0x0,%r11
933 *******************************************************************************/
935 bool patcher_checkcast_class(u1 *sp)
938 java_objectheader *o;
940 constant_classref *cr;
943 /* get stuff from the stack */
945 ra = (u1 *) *((ptrint *) (sp + 4 * 8));
946 o = (java_objectheader *) *((ptrint *) (sp + 3 * 8));
947 mcode = *((u8 *) (sp + 2 * 8));
948 cr = (constant_classref *) *((ptrint *) (sp + 1 * 8));
950 /* calculate and set the new return address */
953 *((ptrint *) (sp + 4 * 8)) = (ptrint) ra;
955 PATCHER_MONITORENTER;
957 /* get the fieldinfo */
959 if (!(c = helper_resolve_classinfo(cr))) {
965 /* patch back original code */
967 *((u8 *) ra) = mcode;
969 /* if we show disassembly, we have to skip the nop's */
971 if (opt_showdisassemble)
974 /* patch super class' vftbl */
976 *((ptrint *) (ra + 2)) = (ptrint) c->vftbl;
977 *((ptrint *) (ra + 10 + 7 + 7 + 3 + 2)) = (ptrint) c->vftbl;
979 PATCHER_MARK_PATCHED_MONITOREXIT;
985 /* patcher_instanceof_class ****************************************************
989 <patched call position>
990 49 ba 00 00 00 00 00 00 00 00 mov $0x0,%r10
992 *******************************************************************************/
994 bool patcher_instanceof_class(u1 *sp)
997 java_objectheader *o;
999 constant_classref *cr;
1002 /* get stuff from the stack */
1004 ra = (u1 *) *((ptrint *) (sp + 4 * 8));
1005 o = (java_objectheader *) *((ptrint *) (sp + 3 * 8));
1006 mcode = *((u8 *) (sp + 2 * 8));
1007 cr = (constant_classref *) *((ptrint *) (sp + 1 * 8));
1009 /* calculate and set the new return address */
1012 *((ptrint *) (sp + 4 * 8)) = (ptrint) ra;
1014 PATCHER_MONITORENTER;
1016 /* get the fieldinfo */
1018 if (!(c = helper_resolve_classinfo(cr))) {
1019 PATCHER_MONITOREXIT;
1024 /* patch back original code */
1026 *((u8 *) ra) = mcode;
1028 /* if we show disassembly, we have to skip the nop's */
1030 if (opt_showdisassemble)
1033 /* patch super class' vftbl */
1035 *((ptrint *) (ra + 2)) = (ptrint) c->vftbl;
1037 PATCHER_MARK_PATCHED_MONITOREXIT;
1043 /* patcher_clinit **************************************************************
1045 May be used for GET/PUTSTATIC and in native stub.
1049 <patched call position>
1050 4d 8b 15 92 ff ff ff mov -110(%rip),%r10
1051 49 89 1a mov %rbx,(%r10)
1053 *******************************************************************************/
1055 bool patcher_clinit(u1 *sp)
1058 java_objectheader *o;
1062 /* get stuff from the stack */
1064 ra = (u1 *) *((ptrint *) (sp + 4 * 8));
1065 o = (java_objectheader *) *((ptrint *) (sp + 3 * 8));
1066 mcode = *((u8 *) (sp + 2 * 8));
1067 c = (classinfo *) *((ptrint *) (sp + 1 * 8));
1069 /* calculate and set the new return address */
1072 *((ptrint *) (sp + 4 * 8)) = (ptrint) ra;
1074 PATCHER_MONITORENTER;
1076 /* check if the class is initialized */
1078 if (!initialize_class(c)) {
1079 PATCHER_MONITOREXIT;
1084 /* patch back original code */
1086 *((u8 *) ra) = mcode;
1088 PATCHER_MARK_PATCHED_MONITOREXIT;
1094 /* patcher_resolve_native ******************************************************
1098 <patched call position>
1099 48 b8 00 00 00 00 00 00 00 00 mov $0x0,%rax
1100 48 ff d0 callq *%rax
1102 *******************************************************************************/
1104 #if !defined(ENABLE_STATICVM)
1105 bool patcher_resolve_native(u1 *sp)
1108 java_objectheader *o;
1113 /* get stuff from the stack */
1115 ra = (u1 *) *((ptrint *) (sp + 4 * 8));
1116 o = (java_objectheader *) *((ptrint *) (sp + 3 * 8));
1117 mcode = *((u8 *) (sp + 2 * 8));
1118 m = (methodinfo *) *((ptrint *) (sp + 1 * 8));
1120 /* calculate and set the new return address */
1123 *((ptrint *) (sp + 4 * 8)) = (ptrint) ra;
1125 PATCHER_MONITORENTER;
1127 /* resolve native function */
1129 if (!(f = native_resolve_function(m))) {
1130 PATCHER_MONITOREXIT;
1135 /* patch back original code */
1137 *((u8 *) ra) = mcode;
1139 /* if we show disassembly, we have to skip the nop's */
1141 if (opt_showdisassemble)
1144 /* patch native function pointer */
1146 *((ptrint *) (ra + 2)) = (ptrint) f;
1148 PATCHER_MARK_PATCHED_MONITOREXIT;
1152 #endif /* !defined(ENABLE_STATICVM) */
1156 * These are local overrides for various environment variables in Emacs.
1157 * Please do not remove this and leave it at the end of the file, where
1158 * Emacs will automagically detect them.
1159 * ---------------------------------------------------------------------
1162 * indent-tabs-mode: t
1166 * vim:noexpandtab:sw=4:ts=4: