/* src/vm/jit/x86_64/patcher.c - x86_64 code patching functions
- Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
+ Copyright (C) 1996-2005, 2006, 2007 R. Grafl, A. Krall, C. Kruegel,
C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
J. Wenninger, Institut f. Computersprachen - TU Wien
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA.
- Contact: cacao@cacaojvm.org
-
- Authors: Christian Thalinger
-
- Changes:
-
- $Id: patcher.c 5142 2006-07-17 09:47:02Z twisti $
+ $Id: patcher.c 7590 2007-03-28 18:54:02Z twisti $
*/
#include "vm/jit/x86_64/codegen.h"
#include "mm/memory.h"
+
#include "native/native.h"
+
#include "vm/builtin.h"
-#include "vm/class.h"
#include "vm/exceptions.h"
-#include "vm/field.h"
#include "vm/initialize.h"
-#include "vm/options.h"
-#include "vm/references.h"
-#include "vm/resolve.h"
+
#include "vm/jit/patcher.h"
+#include "vm/jit/stacktrace.h"
+
+#include "vmcore/class.h"
+#include "vmcore/field.h"
+#include "vmcore/options.h"
+#include "vmcore/references.h"
+#include "vm/resolve.h"
/* patcher_wrapper *************************************************************
/* RA is passed as NULL, but the XPC is correct and can be used in
stacktrace_create_extern_stackframeinfo for
- md_codegen_findmethod. */
+ md_codegen_get_pv_from_pc. */
stacktrace_create_extern_stackframeinfo(&sfi, pv, sp + 6 * 8, xpc, xpc);
unresolved_field *uf;
s4 disp;
fieldinfo *fi;
- s4 offset;
/* get stuff from the stack */
/* if we show disassembly, we have to skip the nop's */
- if (opt_showdisassemble)
+ if (opt_shownops)
ra = ra + 5;
- /* get RIP offset from machine instruction */
-
- offset = *((u4 *) (ra + 3));
+ /* patch the field value's address */
- /* patch the field value's address (+ 7: is the size of the RIP move) */
-
- *((ptrint *) (ra + 7 + offset)) = (ptrint) &(fi->value);
+ *((ptrint *) (ra + 7 + disp)) = (ptrint) &(fi->value);
return true;
}
/* if we show disassembly, we have to skip the nop's */
- if (opt_showdisassemble)
+ if (opt_shownops)
ra = ra + 5;
/* patch the field's offset: we check for the field type, because the */
/* if we show disassembly, we have to skip the nop's */
- if (opt_showdisassemble)
+ if (opt_shownops)
ra = ra + 5;
/* patch the field's offset */
/* if we show disassembly, we have to skip the nop's */
- if (opt_showdisassemble)
+ if (opt_shownops)
ra = ra + 5;
/* patch the classinfo pointer */
/* if we show disassembly, we have to skip the nop's */
- if (opt_showdisassemble)
+ if (opt_shownops)
ra = ra + 5;
/* patch the classinfo pointer */
*((ptrint *) (ra + 10 + 2)) = (ptrint) c;
- /* patch new function address */
-
- *((ptrint *) (ra + 10 + 10 + 3 + 2)) = (ptrint) BUILTIN_multianewarray;
-
return true;
}
/* if we show disassembly, we have to skip the nop's */
- if (opt_showdisassemble)
+ if (opt_shownops)
ra = ra + 5;
/* patch the classinfo pointer */
u1 *ra;
u8 mcode;
unresolved_method *um;
+ s4 disp;
methodinfo *m;
/* get stuff from the stack */
ra = (u1 *) *((ptrint *) (sp + 5 * 8));
mcode = *((u8 *) (sp + 3 * 8));
um = (unresolved_method *) *((ptrint *) (sp + 2 * 8));
+ disp = *((s4 *) (sp + 1 * 8));
/* get the fieldinfo */
/* if we show disassembly, we have to skip the nop's */
- if (opt_showdisassemble)
- ra = ra + 5;
+ if (opt_shownops)
+ ra = ra + PATCHER_CALL_SIZE;
/* patch stubroutine */
- *((ptrint *) (ra + 2)) = (ptrint) m->stubroutine;
+/* *((ptrint *) (ra + 2)) = (ptrint) m->stubroutine; */
+ *((ptrint *) (ra + 7 + disp)) = (ptrint) m->stubroutine;
return true;
}
/* if we show disassembly, we have to skip the nop's */
- if (opt_showdisassemble)
+ if (opt_shownops)
ra = ra + 5;
/* patch vftbl index */
/* if we show disassembly, we have to skip the nop's */
- if (opt_showdisassemble)
+ if (opt_shownops)
ra = ra + 5;
/* patch interfacetable index */
/* if we show disassembly, we have to skip the nop's */
- if (opt_showdisassemble)
+ if (opt_shownops)
ra = ra + 5;
/* patch class flags */
}
-/* patcher_checkcast_instanceof_interface **************************************
+/* patcher_checkcast_interface *************************************************
Machine code:
<patched call position>
45 8b 9a 1c 00 00 00 mov 0x1c(%r10),%r11d
- 49 81 eb 00 00 00 00 sub $0x0,%r11
- 4d 85 db test %r11,%r11
- 0f 8e 94 04 00 00 jle 0x00002aaaaab018f8
+ 41 81 fb 00 00 00 00 cmp $0x0,%r11d
+ 0f 8f 08 00 00 00 jg 0x00002aaaaae511d5
+ 48 8b 0c 25 03 00 00 00 mov 0x3,%rcx
4d 8b 9a 00 00 00 00 mov 0x0(%r10),%r11
*******************************************************************************/
-bool patcher_checkcast_instanceof_interface(u1 *sp)
+bool patcher_checkcast_interface(u1 *sp)
{
u1 *ra;
u8 mcode;
/* if we show disassembly, we have to skip the nop's */
- if (opt_showdisassemble)
- ra = ra + 5;
+ if (opt_shownops)
+ ra = ra + PATCHER_CALL_SIZE;
/* patch super class index */
*((s4 *) (ra + 7 + 3)) = (s4) c->index;
- *((s4 *) (ra + 7 + 7 + 3 + 6 + 3)) =
+ *((s4 *) (ra + 7 + 7 + 6 + 8 + 3)) =
(s4) (OFFSET(vftbl_t, interfacetable[0]) -
c->index * sizeof(methodptr*));
/* if we show disassembly, we have to skip the nop's */
- if (opt_showdisassemble)
+ if (opt_shownops)
ra = ra + 5;
/* patch super class' vftbl */
}
+/* patcher_instanceof_interface ************************************************
+
+ Machine code:
+
+ <patched call position>
+ 45 8b 9a 1c 00 00 00 mov 0x1c(%r10),%r11d
+ 41 81 fb 00 00 00 00 cmp $0x0,%r11d
+ 0f 8e 94 04 00 00 jle 0x00002aaaaab018f8
+ 4d 8b 9a 00 00 00 00 mov 0x0(%r10),%r11
+
+*******************************************************************************/
+
+bool patcher_instanceof_interface(u1 *sp)
+{
+ u1 *ra;
+ u8 mcode;
+ constant_classref *cr;
+ classinfo *c;
+
+ /* get stuff from the stack */
+
+ ra = (u1 *) *((ptrint *) (sp + 5 * 8));
+ mcode = *((u8 *) (sp + 3 * 8));
+ cr = (constant_classref *) *((ptrint *) (sp + 2 * 8));
+
+ /* get the fieldinfo */
+
+ if (!(c = resolve_classref_eager(cr)))
+ return false;
+
+ /* patch back original code */
+
+ *((u8 *) ra) = mcode;
+
+ /* if we show disassembly, we have to skip the nop's */
+
+ if (opt_shownops)
+ ra = ra + PATCHER_CALL_SIZE;
+
+ /* patch super class index */
+
+ *((s4 *) (ra + 7 + 3)) = (s4) c->index;
+
+ *((s4 *) (ra + 7 + 7 + 6 + 3)) =
+ (s4) (OFFSET(vftbl_t, interfacetable[0]) -
+ c->index * sizeof(methodptr*));
+
+ return true;
+}
+
+
/* patcher_instanceof_class ****************************************************
Machine code:
/* if we show disassembly, we have to skip the nop's */
- if (opt_showdisassemble)
+ if (opt_shownops)
ra = ra + 5;
/* patch super class' vftbl */
u1 *ra;
u8 mcode;
unresolved_class *uc;
- classinfo *c;
/* get stuff from the stack */
mcode = *((u8 *) (sp + 3 * 8));
uc = (unresolved_class *) *((ptrint *) (sp + 2 * 8));
- /* resolve the class */
+ /* resolve the class and check subtype constraints */
- if (!resolve_class(uc, resolveEager, false, &c))
+ if (!resolve_class_eager_no_access_check(uc))
return false;
/* patch back original code */
/* if we show disassembly, we have to skip the nop's */
- if (opt_showdisassemble)
+ if (opt_shownops)
ra = ra + 5;
/* patch native function pointer */