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 2779 2005-06-22 10:28:54Z 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 bool helper_initialize_class(void* beginOfJavaStack,classinfo *c,u1 *ra)
52 if (!c->initialized) {
53 native_stackframeinfo sfi;
56 /* more or less the same as the above sfi setup is done in the assembler code by the prepare/remove functions*/
57 sfi.returnToFromNative = (functionptr) (ptrint) ra;
58 sfi.beginOfJavaStackframe = beginOfJavaStack;
59 sfi.method = NULL; /*internal*/
60 sfi.addressOfThreadspecificHead = builtin_asm_get_stackframeinfo();
61 sfi.oldThreadspecificHeadValue = *(sfi.addressOfThreadspecificHead);
62 *(sfi.addressOfThreadspecificHead) = &sfi;
64 /*printf("calling static initializer (helper_initialize_class), returnaddress=%p for class %s\n",ra,c->name->text);*/
66 init=initialize_class(c);
68 *(sfi.addressOfThreadspecificHead) = sfi.oldThreadspecificHeadValue;
78 /* patcher_get_putstatic *******************************************************
82 <patched call position>
83 4d 8b 15 86 fe ff ff mov -378(%rip),%r10
84 49 8b 32 mov (%r10),%rsi
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 /* calculate and set the new return address */
110 *((ptrint *) (sp + 3 * 8)) = (ptrint) ra;
112 PATCHER_MONITORENTER;
114 /* get the fieldinfo */
116 if (!(fi = helper_resolve_fieldinfo(uf))) {
122 /* check if the field's class is initialized */
124 if (!helper_initialize_class(beginJavaStack, fi->class, ra + 5)) {
130 /* patch back original code */
132 *((u8 *) ra) = mcode;
134 /* if we show disassembly, we have to skip the nop's */
139 /* get RIP offset from machine instruction */
141 offset = *((u4 *) (ra + 3));
143 /* patch the field value's address (+ 7: is the size of the RIP move) */
145 *((ptrint *) (ra + 7 + offset)) = (ptrint) &(fi->value);
147 PATCHER_MARK_PATCHED_MONITOREXIT;
153 /* patcher_get_putfield ********************************************************
157 <patched call position>
158 45 8b 8f 00 00 00 00 mov 0x0(%r15),%r9d
160 *******************************************************************************/
162 bool patcher_get_putfield(u1 *sp)
165 java_objectheader *o;
167 unresolved_field *uf;
171 /* get stuff from the stack */
173 ra = (u1 *) *((ptrint *) (sp + 3 * 8));
174 o = (java_objectheader *) *((ptrint *) (sp + 2 * 8));
175 mcode = *((u8 *) (sp + 1 * 8));
176 uf = (unresolved_field *) *((ptrint *) (sp + 0 * 8));
178 /* calculate and set the new return address */
181 *((ptrint *) (sp + 3 * 8)) = (ptrint) ra;
183 PATCHER_MONITORENTER;
185 /* get the fieldinfo */
187 if (!(fi = helper_resolve_fieldinfo(uf))) {
193 /* patch back original code (instruction code is smaller than 8 bytes) */
195 *((u4 *) (ra + 0)) = (u4) mcode;
196 *((u1 *) (ra + 4)) = (u1) (mcode >> 32);
198 /* if we show disassembly, we have to skip the nop's */
203 /* patch the field's offset: we check for the field type, because the */
204 /* instructions have different lengths */
206 if (IS_INT_LNG_TYPE(fi->type)) {
207 /* check for special case: %rsp or %r12 as base register */
212 *((u4 *) (ra + 4)) = (u4) (fi->offset);
214 *((u4 *) (ra + 3)) = (u4) (fi->offset);
217 /* check for special case: %rsp or %r12 as base register */
222 *((u4 *) (ra + 6)) = (u4) (fi->offset);
224 *((u4 *) (ra + 5)) = (u4) (fi->offset);
227 PATCHER_MARK_PATCHED_MONITOREXIT;
233 /* patcher_putfieldconst *******************************************************
237 <patched call position>
238 41 c7 85 00 00 00 00 7b 00 00 00 movl $0x7b,0x0(%r13)
240 *******************************************************************************/
242 bool patcher_putfieldconst(u1 *sp)
245 java_objectheader *o;
247 unresolved_field *uf;
250 /* get stuff from the stack */
252 ra = (u1 *) *((ptrint *) (sp + 3 * 8));
253 o = (java_objectheader *) *((ptrint *) (sp + 2 * 8));
254 mcode = *((u8 *) (sp + 1 * 8));
255 uf = (unresolved_field *) *((ptrint *) (sp + 0 * 8));
257 /* calculate and set the new return address */
260 *((ptrint *) (sp + 3 * 8)) = (ptrint) ra;
262 PATCHER_MONITORENTER;
264 /* get the fieldinfo */
266 if (!(fi = helper_resolve_fieldinfo(uf))) {
272 /* patch back original code */
274 *((u8 *) ra) = mcode;
276 /* if we show disassembly, we have to skip the nop's */
281 /* patch the field's offset */
283 if (IS_2_WORD_TYPE(fi->type) || IS_ADR_TYPE(fi->type)) {
284 /* handle special case when the base register is %r12 */
286 if (*(ra + 2) == 0x84) {
287 *((u4 *) (ra + 4)) = (u4) (fi->offset);
288 *((u4 *) (ra + 12 + 4)) = (u4) (fi->offset + 4);
291 *((u4 *) (ra + 3)) = (u4) (fi->offset);
292 *((u4 *) (ra + 11 + 3)) = (u4) (fi->offset + 4);
296 /* handle special case when the base register is %r12 */
298 if (*(ra + 2) == 0x84)
299 *((u4 *) (ra + 4)) = (u4) (fi->offset);
301 *((u4 *) (ra + 3)) = (u4) (fi->offset);
304 PATCHER_MARK_PATCHED_MONITOREXIT;
310 /* patcher_builtin_new *********************************************************
314 48 bf a0 f0 92 00 00 00 00 00 mov $0x92f0a0,%rdi
315 <patched call position>
316 48 b8 00 00 00 00 00 00 00 00 mov $0x0,%rax
319 *******************************************************************************/
321 bool patcher_builtin_new(u1 *sp)
324 java_objectheader *o;
326 constant_classref *cr;
328 void *beginJavaStack;
329 /* get stuff from the stack */
331 ra = (u1 *) *((ptrint *) (sp + 3 * 8));
332 o = (java_objectheader *) *((ptrint *) (sp + 2 * 8));
333 mcode = *((u8 *) (sp + 1 * 8));
334 cr = (constant_classref *) *((ptrint *) (sp + 0 * 8));
335 beginJavaStack = (void*) (sp+3*8);
337 /* calculate and set the new return address */
340 *((ptrint *) (sp + 3 * 8)) = (ptrint) ra;
342 PATCHER_MONITORENTER;
344 /* get the classinfo */
346 if (!(c = helper_resolve_classinfo(cr))) {
352 if (!helper_initialize_class(beginJavaStack, c, ra + 5)) {
358 /* patch back original code */
360 *((u8 *) (ra + 10)) = mcode;
362 /* patch the classinfo pointer */
364 *((ptrint *) (ra + 2)) = (ptrint) c;
366 /* if we show disassembly, we have to skip the nop's */
371 /* patch new function address */
373 *((ptrint *) (ra + 10 + 2)) = (ptrint) BUILTIN_new;
375 PATCHER_MARK_PATCHED_MONITOREXIT;
381 /* patcher_builtin_newarray ****************************************************
385 48 be 88 13 9b 00 00 00 00 00 mov $0x9b1388,%rsi
386 <patched call position>
387 48 b8 00 00 00 00 00 00 00 00 mov $0x0,%rax
390 *******************************************************************************/
392 bool patcher_builtin_newarray(u1 *sp)
395 java_objectheader *o;
397 constant_classref *cr;
400 /* get stuff from the stack */
402 ra = (u1 *) *((ptrint *) (sp + 3 * 8));
403 o = (java_objectheader *) *((ptrint *) (sp + 2 * 8));
404 mcode = *((u8 *) (sp + 1 * 8));
405 cr = (constant_classref *) *((ptrint *) (sp + 0 * 8));
407 /* calculate and set the new return address */
410 *((ptrint *) (sp + 3 * 8)) = (ptrint) ra;
412 PATCHER_MONITORENTER;
414 /* get the classinfo */
416 if (!(c = helper_resolve_classinfo(cr))) {
422 /* patch back original code */
424 *((u8 *) (ra + 10)) = mcode;
426 /* patch the class' vftbl pointer */
428 *((ptrint *) (ra + 2)) = (ptrint) c->vftbl;
430 /* if we show disassembly, we have to skip the nop's */
435 /* patch new function address */
437 *((ptrint *) (ra + 10 + 2)) = (ptrint) BUILTIN_newarray;
439 PATCHER_MARK_PATCHED_MONITOREXIT;
445 /* patcher_builtin_multianewarray **********************************************
449 <patched call position>
450 48 bf 02 00 00 00 00 00 00 00 mov $0x2,%rdi
451 48 be 30 40 b2 00 00 00 00 00 mov $0xb24030,%rsi
452 48 89 e2 mov %rsp,%rdx
453 48 b8 7c 96 4b 00 00 00 00 00 mov $0x4b967c,%rax
456 *******************************************************************************/
458 bool patcher_builtin_multianewarray(u1 *sp)
461 java_objectheader *o;
463 constant_classref *cr;
466 /* get stuff from the stack */
468 ra = (u1 *) *((ptrint *) (sp + 3 * 8));
469 o = (java_objectheader *) *((ptrint *) (sp + 2 * 8));
470 mcode = *((u8 *) (sp + 1 * 8));
471 cr = (constant_classref *) *((ptrint *) (sp + 0 * 8));
473 /* calculate and set the new return address */
476 *((ptrint *) (sp + 3 * 8)) = (ptrint) ra;
478 PATCHER_MONITORENTER;
480 /* get the classinfo */
482 if (!(c = helper_resolve_classinfo(cr))) {
488 /* patch back original code */
490 *((u8 *) ra) = mcode;
492 /* if we show disassembly, we have to skip the nop's */
497 /* patch the class' vftbl pointer */
499 *((ptrint *) (ra + 10 + 2)) = (ptrint) c->vftbl;
501 /* patch new function address */
503 *((ptrint *) (ra + 10 + 10 + 3 + 2)) = (ptrint) BUILTIN_multianewarray;
505 PATCHER_MARK_PATCHED_MONITOREXIT;
511 /* patcher_builtin_arraycheckcast **********************************************
515 48 be b8 3f b2 00 00 00 00 00 mov $0xb23fb8,%rsi
516 <patched call position>
517 48 b8 00 00 00 00 00 00 00 00 mov $0x0,%rax
520 *******************************************************************************/
522 bool patcher_builtin_arraycheckcast(u1 *sp)
525 java_objectheader *o;
527 constant_classref *cr;
530 /* get stuff from the stack */
532 ra = (u1 *) *((ptrint *) (sp + 3 * 8));
533 o = (java_objectheader *) *((ptrint *) (sp + 2 * 8));
534 mcode = *((u8 *) (sp + 1 * 8));
535 cr = (constant_classref *) *((ptrint *) (sp + 0 * 8));
537 /* calculate and set the new return address */
540 *((ptrint *) (sp + 3 * 8)) = (ptrint) ra;
542 PATCHER_MONITORENTER;
544 /* get the classinfo */
546 if (!(c = helper_resolve_classinfo(cr))) {
552 /* patch back original code */
554 *((u8 *) (ra + 10)) = mcode;
556 /* patch the class' vftbl pointer */
558 *((ptrint *) (ra + 2)) = (ptrint) c->vftbl;
560 /* if we show disassembly, we have to skip the nop's */
565 /* patch new function address */
567 *((ptrint *) (ra + 10 + 2)) = (ptrint) BUILTIN_arraycheckcast;
569 PATCHER_MARK_PATCHED_MONITOREXIT;
575 /* patcher_builtin_arrayinstanceof *********************************************
579 48 be 30 3c b2 00 00 00 00 00 mov $0xb23c30,%rsi
580 <patched call position>
581 48 b8 00 00 00 00 00 00 00 00 mov $0x0,%rax
584 *******************************************************************************/
586 bool patcher_builtin_arrayinstanceof(u1 *sp)
589 java_objectheader *o;
591 constant_classref *cr;
594 /* get stuff from the stack */
596 ra = (u1 *) *((ptrint *) (sp + 3 * 8));
597 o = (java_objectheader *) *((ptrint *) (sp + 2 * 8));
598 mcode = *((u8 *) (sp + 1 * 8));
599 cr = (constant_classref *) *((ptrint *) (sp + 0 * 8));
601 /* calculate and set the new return address */
604 *((ptrint *) (sp + 3 * 8)) = (ptrint) ra;
606 PATCHER_MONITORENTER;
608 /* get the classinfo */
610 if (!(c = helper_resolve_classinfo(cr))) {
616 /* patch back original code */
618 *((u8 *) (ra + 10)) = mcode;
620 /* patch the class' vftbl pointer */
622 *((ptrint *) (ra + 2)) = (ptrint) c->vftbl;
624 /* if we show disassembly, we have to skip the nop's */
629 /* patch new function address */
631 *((ptrint *) (ra + 10 + 2)) = (ptrint) BUILTIN_arrayinstanceof;
633 PATCHER_MARK_PATCHED_MONITOREXIT;
639 /* patcher_invokestatic_special ************************************************
643 <patched call position>
644 49 ba 00 00 00 00 00 00 00 00 mov $0x0,%r10
647 *******************************************************************************/
649 bool patcher_invokestatic_special(u1 *sp)
652 java_objectheader *o;
654 unresolved_method *um;
657 /* get stuff from the stack */
659 ra = (u1 *) *((ptrint *) (sp + 3 * 8));
660 o = (java_objectheader *) *((ptrint *) (sp + 2 * 8));
661 mcode = *((u8 *) (sp + 1 * 8));
662 um = (unresolved_method *) *((ptrint *) (sp + 0 * 8));
664 /* calculate and set the new return address */
667 *((ptrint *) (sp + 3 * 8)) = (ptrint) ra;
669 PATCHER_MONITORENTER;
671 /* get the fieldinfo */
673 if (!(m = helper_resolve_methodinfo(um))) {
678 /* patch back original code */
680 *((u8 *) ra) = mcode;
682 /* if we show disassembly, we have to skip the nop's */
687 /* patch stubroutine */
689 *((ptrint *) (ra + 2)) = (ptrint) m->stubroutine;
691 PATCHER_MARK_PATCHED_MONITOREXIT;
697 /* patcher_invokevirtual *******************************************************
701 <patched call position>
702 4c 8b 17 mov (%rdi),%r10
703 49 8b 82 00 00 00 00 mov 0x0(%r10),%rax
706 *******************************************************************************/
708 bool patcher_invokevirtual(u1 *sp)
711 java_objectheader *o;
713 unresolved_method *um;
716 /* get stuff from the stack */
718 ra = (u1 *) *((ptrint *) (sp + 3 * 8));
719 o = (java_objectheader *) *((ptrint *) (sp + 2 * 8));
720 mcode = *((u8 *) (sp + 1 * 8));
721 um = (unresolved_method *) *((ptrint *) (sp + 0 * 8));
723 /* calculate and set the new return address */
726 *((ptrint *) (sp + 3 * 8)) = (ptrint) ra;
728 PATCHER_MONITORENTER;
730 /* get the fieldinfo */
732 if (!(m = helper_resolve_methodinfo(um))) {
738 /* patch back original code */
740 *((u8 *) ra) = mcode;
742 /* if we show disassembly, we have to skip the nop's */
747 /* patch vftbl index */
749 *((s4 *) (ra + 3 + 3)) = (s4) (OFFSET(vftbl_t, table[0]) +
750 sizeof(methodptr) * m->vftblindex);
752 PATCHER_MARK_PATCHED_MONITOREXIT;
758 /* patcher_invokeinterface *****************************************************
762 <patched call position>
763 4c 8b 17 mov (%rdi),%r10
764 4d 8b 92 00 00 00 00 mov 0x0(%r10),%r10
765 49 8b 82 00 00 00 00 mov 0x0(%r10),%rax
768 *******************************************************************************/
770 bool patcher_invokeinterface(u1 *sp)
773 java_objectheader *o;
775 unresolved_method *um;
778 /* get stuff from the stack */
780 ra = (u1 *) *((ptrint *) (sp + 3 * 8));
781 o = (java_objectheader *) *((ptrint *) (sp + 2 * 8));
782 mcode = *((u8 *) (sp + 1 * 8));
783 um = (unresolved_method *) *((ptrint *) (sp + 0 * 8));
785 /* calculate and set the new return address */
788 *((ptrint *) (sp + 3 * 8)) = (ptrint) ra;
790 PATCHER_MONITORENTER;
792 /* get the fieldinfo */
794 if (!(m = helper_resolve_methodinfo(um))) {
800 /* patch back original code */
802 *((u8 *) ra) = mcode;
804 /* if we show disassembly, we have to skip the nop's */
809 /* patch interfacetable index */
811 *((s4 *) (ra + 3 + 3)) = (s4) (OFFSET(vftbl_t, interfacetable[0]) -
812 sizeof(methodptr) * m->class->index);
814 /* patch method offset */
816 *((s4 *) (ra + 3 + 7 + 3)) =
817 (s4) (sizeof(methodptr) * (m - m->class->methods));
819 PATCHER_MARK_PATCHED_MONITOREXIT;
825 /* patcher_checkcast_instanceof_flags ******************************************
829 <patched call position>
830 41 ba 00 00 00 00 mov $0x0,%r10d
831 41 81 e2 00 02 00 00 and $0x200,%r10d
832 0f 84 35 00 00 00 je 0x00002aaaaab01479
834 *******************************************************************************/
836 bool patcher_checkcast_instanceof_flags(u1 *sp)
839 java_objectheader *o;
841 constant_classref *cr;
844 /* get stuff from the stack */
846 ra = (u1 *) *((ptrint *) (sp + 3 * 8));
847 o = (java_objectheader *) *((ptrint *) (sp + 2 * 8));
848 mcode = *((u8 *) (sp + 1 * 8));
849 cr = (constant_classref *) *((ptrint *) (sp + 0 * 8));
851 /* calculate and set the new return address */
854 *((ptrint *) (sp + 3 * 8)) = (ptrint) ra;
856 PATCHER_MONITORENTER;
858 /* get the fieldinfo */
860 if (!(c = helper_resolve_classinfo(cr))) {
866 /* patch back original code */
868 *((u8 *) ra) = mcode;
870 /* if we show disassembly, we have to skip the nop's */
875 /* patch class flags */
877 *((s4 *) (ra + 2)) = (s4) c->flags;
879 PATCHER_MARK_PATCHED_MONITOREXIT;
885 /* patcher_checkcast_instanceof_interface **************************************
889 <patched call position>
890 45 8b 9a 1c 00 00 00 mov 0x1c(%r10),%r11d
891 49 81 eb 00 00 00 00 sub $0x0,%r11
892 4d 85 db test %r11,%r11
893 0f 8e 94 04 00 00 jle 0x00002aaaaab018f8
894 4d 8b 9a 00 00 00 00 mov 0x0(%r10),%r11
896 *******************************************************************************/
898 bool patcher_checkcast_instanceof_interface(u1 *sp)
901 java_objectheader *o;
903 constant_classref *cr;
906 /* get stuff from the stack */
908 ra = (u1 *) *((ptrint *) (sp + 3 * 8));
909 o = (java_objectheader *) *((ptrint *) (sp + 2 * 8));
910 mcode = *((u8 *) (sp + 1 * 8));
911 cr = (constant_classref *) *((ptrint *) (sp + 0 * 8));
913 /* calculate and set the new return address */
916 *((ptrint *) (sp + 3 * 8)) = (ptrint) ra;
918 PATCHER_MONITORENTER;
920 /* get the fieldinfo */
922 if (!(c = helper_resolve_classinfo(cr))) {
928 /* patch back original code */
930 *((u8 *) ra) = mcode;
932 /* if we show disassembly, we have to skip the nop's */
937 /* patch super class index */
939 *((s4 *) (ra + 7 + 3)) = (s4) c->index;
941 *((s4 *) (ra + 7 + 7 + 3 + 6 + 3)) =
942 (s4) (OFFSET(vftbl_t, interfacetable[0]) -
943 c->index * sizeof(methodptr*));
945 PATCHER_MARK_PATCHED_MONITOREXIT;
951 /* patcher_checkcast_class *****************************************************
955 <patched call position>
956 49 bb 00 00 00 00 00 00 00 00 mov $0x0,%r11
957 45 8b 92 20 00 00 00 mov 0x20(%r10),%r10d
958 45 8b 9b 20 00 00 00 mov 0x20(%r11),%r11d
959 4d 29 da sub %r11,%r10
960 49 bb 00 00 00 00 00 00 00 00 mov $0x0,%r11
962 *******************************************************************************/
964 bool patcher_checkcast_class(u1 *sp)
967 java_objectheader *o;
969 constant_classref *cr;
972 /* get stuff from the stack */
974 ra = (u1 *) *((ptrint *) (sp + 3 * 8));
975 o = (java_objectheader *) *((ptrint *) (sp + 2 * 8));
976 mcode = *((u8 *) (sp + 1 * 8));
977 cr = (constant_classref *) *((ptrint *) (sp + 0 * 8));
979 /* calculate and set the new return address */
982 *((ptrint *) (sp + 3 * 8)) = (ptrint) ra;
984 PATCHER_MONITORENTER;
986 /* get the fieldinfo */
988 if (!(c = helper_resolve_classinfo(cr))) {
994 /* patch back original code */
996 *((u8 *) ra) = mcode;
998 /* if we show disassembly, we have to skip the nop's */
1000 if (showdisassemble)
1003 /* patch super class' vftbl */
1005 *((ptrint *) (ra + 2)) = (ptrint) c->vftbl;
1006 *((ptrint *) (ra + 10 + 7 + 7 + 3 + 2)) = (ptrint) c->vftbl;
1008 PATCHER_MARK_PATCHED_MONITOREXIT;
1014 /* patcher_instanceof_class ****************************************************
1018 <patched call position>
1019 49 ba 00 00 00 00 00 00 00 00 mov $0x0,%r10
1021 *******************************************************************************/
1023 bool patcher_instanceof_class(u1 *sp)
1026 java_objectheader *o;
1028 constant_classref *cr;
1031 /* get stuff from the stack */
1033 ra = (u1 *) *((ptrint *) (sp + 3 * 8));
1034 o = (java_objectheader *) *((ptrint *) (sp + 2 * 8));
1035 mcode = *((u8 *) (sp + 1 * 8));
1036 cr = (constant_classref *) *((ptrint *) (sp + 0 * 8));
1038 /* calculate and set the new return address */
1041 *((ptrint *) (sp + 3 * 8)) = (ptrint) ra;
1043 PATCHER_MONITORENTER;
1045 /* get the fieldinfo */
1047 if (!(c = helper_resolve_classinfo(cr))) {
1048 PATCHER_MONITOREXIT;
1053 /* patch back original code */
1055 *((u8 *) ra) = mcode;
1057 /* if we show disassembly, we have to skip the nop's */
1059 if (showdisassemble)
1062 /* patch super class' vftbl */
1064 *((ptrint *) (ra + 2)) = (ptrint) c->vftbl;
1066 PATCHER_MARK_PATCHED_MONITOREXIT;
1072 /* patcher_clinit **************************************************************
1074 May be used for GET/PUTSTATIC and in native stub.
1078 <patched call position>
1079 4d 8b 15 92 ff ff ff mov -110(%rip),%r10
1080 49 89 1a mov %rbx,(%r10)
1082 *******************************************************************************/
1084 bool patcher_clinit(u1 *sp)
1087 java_objectheader *o;
1090 void *beginJavaStack;
1092 /* get stuff from the stack */
1094 ra = (u1 *) *((ptrint *) (sp + 3 * 8));
1095 o = (java_objectheader *) *((ptrint *) (sp + 2 * 8));
1096 mcode = *((u8 *) (sp + 1 * 8));
1097 c = (classinfo *) *((ptrint *) (sp + 0 * 8));
1099 beginJavaStack = (void*) (sp + 3 * 8);
1101 /* calculate and set the new return address */
1104 *((ptrint *) (sp + 3 * 8)) = (ptrint) ra;
1106 PATCHER_MONITORENTER;
1108 /* check if the class is initialized */
1110 if (!helper_initialize_class(beginJavaStack, c, ra + 5)) {
1111 PATCHER_MONITOREXIT;
1116 /* patch back original code */
1118 *((u8 *) ra) = mcode;
1120 PATCHER_MARK_PATCHED_MONITOREXIT;
1126 /* patcher_resolve_native ******************************************************
1130 <patched call position>
1131 48 b8 00 00 00 00 00 00 00 00 mov $0x0,%rax
1132 48 ff d0 callq *%rax
1134 *******************************************************************************/
1136 bool patcher_resolve_native(u1 *sp)
1139 java_objectheader *o;
1143 void *beginJavaStack;
1145 /* get stuff from the stack */
1147 ra = (u1 *) *((ptrint *) (sp + 3 * 8));
1148 o = (java_objectheader *) *((ptrint *) (sp + 2 * 8));
1149 mcode = *((u8 *) (sp + 1 * 8));
1150 m = (methodinfo *) *((ptrint *) (sp + 0 * 8));
1152 beginJavaStack = (void*) (sp + 3 * 8);
1154 /* calculate and set the new return address */
1157 *((ptrint *) (sp + 3 * 8)) = (ptrint) ra;
1159 PATCHER_MONITORENTER;
1161 /* resolve native function */
1163 if (!(f = native_resolve_function(m))) {
1164 PATCHER_MONITOREXIT;
1169 /* patch back original code */
1171 *((u8 *) ra) = mcode;
1173 /* if we show disassembly, we have to skip the nop's */
1175 if (showdisassemble)
1178 /* patch native function pointer */
1180 *((ptrint *) (ra + 2)) = (ptrint) f;
1182 PATCHER_MARK_PATCHED_MONITOREXIT;
1189 * These are local overrides for various environment variables in Emacs.
1190 * Please do not remove this and leave it at the end of the file, where
1191 * Emacs will automagically detect them.
1192 * ---------------------------------------------------------------------
1195 * indent-tabs-mode: t
1199 * vim:noexpandtab:sw=4:ts=4: