/* 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 5945 2006-11-10 16:41:12Z twisti $
-
*/
#include "config.h"
+
+#include <stdint.h>
+
#include "vm/types.h"
#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 *************************************************************
*******************************************************************************/
-java_objectheader *patcher_wrapper(u1 *sp, u1 *pv, u1 *ra)
+java_object_t *patcher_wrapper(u1 *sp, u1 *pv, u1 *ra)
{
stackframeinfo sfi;
u1 *xpc;
- java_objectheader *o;
+ java_object_t *o;
functionptr f;
bool result;
- java_objectheader *e;
+ java_handle_t *e;
/* define the patcher function */
/* get stuff from the stack */
xpc = (u1 *) *((ptrint *) (sp + 5 * 8));
- o = (java_objectheader *) *((ptrint *) (sp + 4 * 8));
+ o = (java_object_t *) *((ptrint *) (sp + 4 * 8));
f = (functionptr) *((ptrint *) (sp + 0 * 8));
/* calculate and set the new return address */
/* patch the field value's address */
- *((ptrint *) (ra + 7 + disp)) = (ptrint) &(fi->value);
+ *((intptr_t *) (ra + 7 + disp)) = (intptr_t) fi->value;
return true;
}
byte = *(ra + 3);
if (byte == 0x24)
- *((u4 *) (ra + 4)) = (u4) (fi->offset);
+ *((int32_t *) (ra + 4)) = fi->offset;
else
- *((u4 *) (ra + 3)) = (u4) (fi->offset);
+ *((int32_t *) (ra + 3)) = fi->offset;
}
else {
/* check for special case: %rsp or %r12 as base register */
byte = *(ra + 5);
if (byte == 0x24)
- *((u4 *) (ra + 6)) = (u4) (fi->offset);
+ *((int32_t *) (ra + 6)) = fi->offset;
else
- *((u4 *) (ra + 5)) = (u4) (fi->offset);
+ *((int32_t *) (ra + 5)) = fi->offset;
}
return true;
/* handle special case when the base register is %r12 */
if (*(ra + 2) == 0x84) {
- *((u4 *) (ra + 4)) = (u4) (fi->offset);
- *((u4 *) (ra + 12 + 4)) = (u4) (fi->offset + 4);
+ *((uint32_t *) (ra + 4)) = fi->offset;
+ *((uint32_t *) (ra + 12 + 4)) = fi->offset + 4;
}
else {
- *((u4 *) (ra + 3)) = (u4) (fi->offset);
- *((u4 *) (ra + 11 + 3)) = (u4) (fi->offset + 4);
+ *((uint32_t *) (ra + 3)) = fi->offset;
+ *((uint32_t *) (ra + 11 + 3)) = fi->offset + 4;
}
}
else {
/* handle special case when the base register is %r12 */
if (*(ra + 2) == 0x84)
- *((u4 *) (ra + 4)) = (u4) (fi->offset);
+ *((uint32_t *) (ra + 4)) = fi->offset;
else
- *((u4 *) (ra + 3)) = (u4) (fi->offset);
+ *((uint32_t *) (ra + 3)) = fi->offset;
}
return true;
/* if we show disassembly, we have to skip the nop's */
if (opt_shownops)
- ra = ra + 5;
+ ra = ra + PATCHER_CALL_SIZE;
/* patch stubroutine */
}
-/* 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_shownops)
- ra = ra + 5;
+ 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*));
}
+/* 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:
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 */