* src/vm/signal.c (signal_init): Likewise.
* src/vm/signallocal.h: Likewise.
* src/vm/jit/x86_64/asmpart.S (asm_patcher_wrapper): Removed.
* src/vm/jit/x86_64/codegen.c (vm/jit/patcher.h): Removed.
(vm/jit/patcher-common.h): Added.
(codegen_emit): Implemented patchers-by-signal and load data from data
segment instead of moving inline.
(codegen_emit_stub_native): Likewise.
(codegen_emit_stub_compiler): Quick hack for ALD.
* src/vm/jit/x86_64/codegen.h (PATCHER_CALL_SIZE): Changed to 2.
(PATCHER_NOPS): Likewise.
(M_ALD): Handle RIP properly.
* src/vm/jit/x86_64/emit.c (vm/jit/patcher-common.h): Added.
(emit_patcher_stubs): Removed.
(emit_trap): Emit UD2.
* src/vm/jit/x86_64/linux/md-os.c (md_signal_handler_sigill): New
function.
* src/vm/jit/x86_64/patcher.c (vm/jit/patcher.h): Removed.
(vm/jit/patcher-common.h): Added.
(patcher_wrapper): Removed.
(PATCH_BACK_ORIGINAL_MCODE): New macro.
(patcher_patch_code): New function.
(patcher_resolve_classref_to_classinfo): Likewise.
(patcher_resolve_classref_to_vftbl): Likewise.
(patcher_resolve_classref_to_flags): Likewise.
(patcher_resolve_native_function): Likewise.
(patcher_aconst): Removed.
(patcher_builtin_multianewarray): Likewise.
(patcher_builtin_arraycheckcast): Likewise.
(patcher_checkcast_instanceof_flags): Likewise.
(patcher_checkcast_class): Likewise.
(patcher_instanceof_class): Likewise.
(patcher_clinit): Likewise.
(patcher_athrow_areturn): Likewise.
(patcher_resolve_native): Likewise.
/* patcher prototypes and macros **********************************************/
-#if defined(__ALPHA__) || defined(__ARM__) || defined(__I386__) || defined(__MIPS__) || defined(__POWERPC__) || defined(__POWERPC64__) || defined (__S390__)
+#if defined(__ALPHA__) || defined(__ARM__) || defined(__I386__) || defined(__MIPS__) || defined(__POWERPC__) || defined(__POWERPC64__) || defined (__S390__) || defined(__X86_64__)
/* new patcher functions */
bool patcher_invokeinterface(patchref_t *pr);
#define PATCHER_invokeinterface (functionptr) patcher_invokeinterface
-#if defined(__ALPHA__) || defined(__I386__) || defined(__MIPS__) || defined(__POWERPC__) || defined(__POWERPC64__) || defined(__S390__)
+#if defined(__ALPHA__) || defined(__I386__) || defined(__MIPS__) || defined(__POWERPC__) || defined(__POWERPC64__) || defined(__S390__) || defined(__X86_64__)
bool patcher_checkcast_interface(patchref_t *pr);
#define PATCHER_checkcast_interface (functionptr) patcher_checkcast_interface
bool patcher_instanceof_interface(patchref_t *pr);
#define PATCHER_instanceof_interface (functionptr) patcher_instanceof_interface
-#endif /* defined(__ALPHA__) || defined(__I386__) || defined(__MIPS__) || defined(__POWERPC__) || defined(__POWERPC64__) || defined(__S390__) */
+#endif /* defined(__ALPHA__) || defined(__I386__) || defined(__MIPS__) || defined(__POWERPC__) || defined(__POWERPC64__) || defined(__S390__) || defined(__X86_64__) */
#if defined(__S390__)
.globl asm_abstractmethoderror
- .globl asm_patcher_wrapper
-
#if defined(ENABLE_REPLACEMENT)
.globl asm_replacement_out
.globl asm_replacement_in
jmp L_asm_handle_exception
-/* asm_patcher_wrapper *********************************************************
-
- XXX
-
- Stack layout:
- 40 return address
- 32 pointer to virtual java_objectheader
- 24 machine code (which is patched back later)
- 16 unresolved class/method/field reference
- 8 data segment displacement from load instructions
- 0 pointer to patcher function
- -8 bp
-
-*******************************************************************************/
-
-asm_patcher_wrapper:
- push bp /* save base pointer */
- mov sp,bp /* move actual sp to bp */
- sub $(3+ARG_CNT+TMP_CNT)*8,sp
- and $0xfffffffffffffff0,sp /* align sp to 16-byte (this is for */
- /* leaf functions) */
-
- SAVE_ARGUMENT_REGISTERS(3)
- SAVE_TEMPORARY_REGISTERS(3+ARG_CNT)
-
- mov itmp1,0*8(sp) /* save itmp1 and itmp2 */
- mov itmp2,1*8(sp) /* can be used by some instructions */
-
- mov bp,a0 /* pass SP of patcher stub */
- add $(1*8),a0
- mov $0,a1 /* pass PV (if NULL, use findmethod) */
- mov $0,a2 /* pass RA (it's on the stack) */
- call patcher_wrapper@PLT
- mov v0,2*8(sp) /* save return value */
-
- RESTORE_ARGUMENT_REGISTERS(3)
- RESTORE_TEMPORARY_REGISTERS(3+ARG_CNT)
-
- mov 0*8(sp),itmp1 /* restore itmp1 and itmp2 */
- mov 1*8(sp),itmp2 /* can be used by some instructions */
- mov 2*8(sp),itmp3 /* restore return value */
-
- mov bp,sp /* restore original sp */
- pop bp /* restore bp */
- add $(5*8),sp /* remove patcher stackframe, keep RA */
-
- test itmp3,itmp3 /* exception thrown? */
- jne L_asm_patcher_wrapper_exception
- ret /* call new patched code */
-
-L_asm_patcher_wrapper_exception:
- mov itmp3,xptr /* get exception */
- pop xpc /* get and remove return address */
- jmp L_asm_handle_exception
-
#if defined(ENABLE_REPLACEMENT)
/* asm_replacement_out *********************************************************
#include "vm/jit/jit.h"
#include "vm/jit/methodheader.h"
#include "vm/jit/parse.h"
-#include "vm/jit/patcher.h"
+#include "vm/jit/patcher-common.h"
#include "vm/jit/reg.h"
#include "vm/jit/replace.h"
#include "vm/jit/stacktrace.h"
d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
- cr = iptr->sx.val.c.ref;
+ cr = iptr->sx.val.c.ref;
+ disp = dseg_add_unique_address(cd, cr);
/* PROFILE_CYCLE_STOP; */
- codegen_add_patch_ref(cd, PATCHER_aconst, cr, 0);
+ patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_classinfo,
+ cr, disp);
/* PROFILE_CYCLE_START; */
- M_MOV_IMM(NULL, d);
-
- } else {
- if (iptr->sx.val.anyptr == 0)
+ M_ALD(d, RIP, disp);
+ }
+ else {
+ if (iptr->sx.val.anyptr == 0) {
M_CLR(d);
- else
- M_MOV_IMM(iptr->sx.val.anyptr, d);
+ }
+ else {
+ disp = dseg_add_address(cd, iptr->sx.val.anyptr);
+ M_ALD(d, RIP, disp);
+ }
}
emit_store_dst(jd, iptr, d);
break;
if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
uf = iptr->sx.s23.s3.uf;
fieldtype = uf->fieldref->parseddesc.fd->type;
- disp = dseg_add_unique_address(cd, NULL);
- disp = disp + -((cd->mcodeptr + 7) - cd->mcodebase);
-
- /* must be calculated before codegen_add_patch_ref */
-
- if (opt_shownops)
- disp -= PATCHER_CALL_SIZE;
+ disp = dseg_add_unique_address(cd, uf);
/* PROFILE_CYCLE_STOP; */
- codegen_add_patch_ref(cd, PATCHER_get_putstatic, uf, disp);
+ patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, disp);
/* PROFILE_CYCLE_START; */
}
fi = iptr->sx.s23.s3.fmiref->p.field;
fieldtype = fi->type;
disp = dseg_add_address(cd, fi->value);
- disp = disp + -((cd->mcodeptr + 7) - cd->mcodebase);
if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
PROFILE_CYCLE_STOP;
- codegen_add_patch_ref(cd, PATCHER_clinit, fi->class, 0);
+ patcher_add_patch_ref(jd, PATCHER_initialize_class,
+ fi->class, 0);
PROFILE_CYCLE_START;
-
- if (opt_shownops)
- disp -= PATCHER_CALL_SIZE;
}
}
if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
uf = iptr->sx.s23.s3.uf;
fieldtype = uf->fieldref->parseddesc.fd->type;
- disp = dseg_add_unique_address(cd, NULL);
- disp = disp + -((cd->mcodeptr + 7) - cd->mcodebase);
-
- /* must be calculated before codegen_add_patch_ref */
-
- if (opt_shownops)
- disp -= PATCHER_CALL_SIZE;
+ disp = dseg_add_unique_address(cd, uf);
/* PROFILE_CYCLE_STOP; */
- codegen_add_patch_ref(cd, PATCHER_get_putstatic, uf, disp);
+ patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, disp);
/* PROFILE_CYCLE_START; */
}
fi = iptr->sx.s23.s3.fmiref->p.field;
fieldtype = fi->type;
disp = dseg_add_address(cd, fi->value);
- disp = disp + -((cd->mcodeptr + 7) - cd->mcodebase);
if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
PROFILE_CYCLE_STOP;
- codegen_add_patch_ref(cd, PATCHER_clinit, fi->class, 0);
+ patcher_add_patch_ref(jd, PATCHER_initialize_class,
+ fi->class, 0);
PROFILE_CYCLE_START;
-
- if (opt_shownops)
- disp -= PATCHER_CALL_SIZE;
}
}
if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
uf = iptr->sx.s23.s3.uf;
fieldtype = uf->fieldref->parseddesc.fd->type;
- disp = dseg_add_unique_address(cd, NULL);
- disp = disp + -((cd->mcodeptr + 7) - cd->mcodebase);
-
- /* must be calculated before codegen_add_patch_ref */
-
- if (opt_shownops)
- disp -= PATCHER_CALL_SIZE;
+ disp = dseg_add_unique_address(cd, uf);
/* PROFILE_CYCLE_STOP; */
- codegen_add_patch_ref(cd, PATCHER_get_putstatic, uf, disp);
+ patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, disp);
/* PROFILE_CYCLE_START; */
}
fi = iptr->sx.s23.s3.fmiref->p.field;
fieldtype = fi->type;
disp = dseg_add_address(cd, fi->value);
- disp = disp + -((cd->mcodeptr + 7) - cd->mcodebase);
if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
PROFILE_CYCLE_STOP;
- codegen_add_patch_ref(cd, PATCHER_clinit, fi->class, 0);
+ patcher_add_patch_ref(jd, PATCHER_initialize_class,
+ fi->class, 0);
PROFILE_CYCLE_START;
-
- if (opt_shownops)
- disp -= PATCHER_CALL_SIZE;
}
}
/* PROFILE_CYCLE_STOP; */
- codegen_add_patch_ref(cd, PATCHER_get_putfield, uf, 0);
+ patcher_add_patch_ref(jd, PATCHER_get_putfield, uf, 0);
/* PROFILE_CYCLE_START; */
}
/* PROFILE_CYCLE_STOP; */
- codegen_add_patch_ref(cd, PATCHER_get_putfield, uf, 0);
+ patcher_add_patch_ref(jd, PATCHER_get_putfield, uf, 0);
/* PROFILE_CYCLE_START; */
}
/* PROFILE_CYCLE_STOP; */
- codegen_add_patch_ref(cd, PATCHER_putfieldconst, uf, 0);
+ patcher_add_patch_ref(jd, PATCHER_putfieldconst, uf, 0);
/* PROFILE_CYCLE_START; */
}
if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
uc = iptr->sx.s23.s2.uc;
- codegen_add_patch_ref(cd, PATCHER_athrow_areturn, uc, 0);
+ patcher_add_patch_ref(jd, PATCHER_resolve_class, uc, 0);
}
#endif /* ENABLE_VERIFIER */
PROFILE_CYCLE_STOP;
- codegen_add_patch_ref(cd, PATCHER_athrow_areturn, uc, 0);
+ patcher_add_patch_ref(jd, PATCHER_resolve_class, uc, 0);
PROFILE_CYCLE_START;
}
case ICMD_INVOKESTATIC:
if (lm == NULL) {
- disp = dseg_add_unique_address(cd, NULL);
- disp = disp + -((cd->mcodeptr + 7) - cd->mcodebase);
-
- /* must be calculated before codegen_add_patch_ref */
+ disp = dseg_add_unique_address(cd, um);
- if (opt_shownops)
- disp -= PATCHER_CALL_SIZE;
-
- codegen_add_patch_ref(cd, PATCHER_invokestatic_special,
+ patcher_add_patch_ref(jd, PATCHER_invokestatic_special,
um, disp);
-
-/* a = 0; */
}
else {
disp = dseg_add_functionptr(cd, lm->stubroutine);
- disp = disp + -((cd->mcodeptr + 7) - cd->mcodebase);
-
-/* a = (ptrint) lm->stubroutine; */
}
-/* M_MOV_IMM(a, REG_ITMP2); */
M_ALD(REG_ITMP2, RIP, disp);
M_CALL(REG_ITMP2);
break;
case ICMD_INVOKEVIRTUAL:
if (lm == NULL) {
- codegen_add_patch_ref(cd, PATCHER_invokevirtual, um, 0);
+ patcher_add_patch_ref(jd, PATCHER_invokevirtual, um, 0);
s1 = 0;
}
case ICMD_INVOKEINTERFACE:
if (lm == NULL) {
- codegen_add_patch_ref(cd, PATCHER_invokeinterface, um, 0);
+ patcher_add_patch_ref(jd, PATCHER_invokeinterface, um, 0);
s1 = 0;
s2 = 0;
/* object type cast-check */
classinfo *super;
- vftbl_t *supervftbl;
s4 superindex;
if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
super = NULL;
superindex = 0;
- supervftbl = NULL;
}
else {
super = iptr->sx.s23.s3.c.cls;
superindex = super->index;
- supervftbl = super->vftbl;
}
if ((super == NULL) || !(super->flags & ACC_INTERFACE))
M_TEST(s1);
emit_label_beq(cd, BRANCH_LABEL_1);
- codegen_add_patch_ref(cd, PATCHER_checkcast_instanceof_flags,
+ patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_flags,
iptr->sx.s23.s3.c.ref, 0);
M_IMOV_IMM(0, REG_ITMP2); /* super->flags */
M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
if (super == NULL) {
- codegen_add_patch_ref(cd, PATCHER_checkcast_interface,
+ patcher_add_patch_ref(jd, PATCHER_checkcast_interface,
iptr->sx.s23.s3.c.ref,
0);
}
if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
if (super == NULL) {
emit_label(cd, BRANCH_LABEL_2);
+
+ cr = iptr->sx.s23.s3.c.ref;
+ disp = dseg_add_unique_address(cd, cr);
+
+ patcher_add_patch_ref(jd,
+ PATCHER_resolve_classref_to_vftbl,
+ cr, disp);
}
else {
M_TEST(s1);
emit_label_beq(cd, BRANCH_LABEL_5);
- }
- M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
-
- if (super == NULL) {
- codegen_add_patch_ref(cd, PATCHER_checkcast_class,
- iptr->sx.s23.s3.c.ref,
- 0);
+ disp = dseg_add_address(cd, super->vftbl);
}
- M_MOV_IMM(supervftbl, REG_ITMP3);
+ M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
+ M_ALD(REG_ITMP3, RIP, disp);
CODEGEN_CRITICAL_SECTION_START;
- M_ILD32(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
+ M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
/* if (s1 != REG_ITMP1) { */
/* emit_movl_membase_reg(cd, REG_ITMP3, */
/* } else { */
- M_ILD32(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, baseval));
+ M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, baseval));
M_ISUB(REG_ITMP3, REG_ITMP2);
- M_MOV_IMM(supervftbl, REG_ITMP3);
+ M_ALD(REG_ITMP3, RIP, disp);
M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval));
/* } */
M_INTMOVE(s1, REG_A0);
if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
- codegen_add_patch_ref(cd, PATCHER_builtin_arraycheckcast,
- iptr->sx.s23.s3.c.ref, 0);
+ cr = iptr->sx.s23.s3.c.ref;
+ disp = dseg_add_unique_address(cd, cr);
+
+ patcher_add_patch_ref(jd,
+ PATCHER_resolve_classref_to_classinfo,
+ cr, disp);
+ }
+ else {
+ disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
}
- M_MOV_IMM(iptr->sx.s23.s3.c.cls, REG_A1);
+ M_ALD(REG_A1, RIP, disp);
M_MOV_IMM(BUILTIN_arraycheckcast, REG_ITMP1);
M_CALL(REG_ITMP1);
{
classinfo *super;
- vftbl_t *supervftbl;
s4 superindex;
if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
super = NULL;
superindex = 0;
- supervftbl = NULL;
}
else {
super = iptr->sx.s23.s3.c.cls;
superindex = super->index;
- supervftbl = super->vftbl;
}
if ((super == NULL) || !(super->flags & ACC_INTERFACE))
M_TEST(s1);
emit_label_beq(cd, BRANCH_LABEL_1);
- codegen_add_patch_ref(cd, PATCHER_checkcast_instanceof_flags,
+ patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_flags,
iptr->sx.s23.s3.c.ref, 0);
M_IMOV_IMM(0, REG_ITMP3); /* super->flags */
M_ALD(REG_ITMP1, s1, OFFSET(java_object_t, vftbl));
if (super == NULL) {
- codegen_add_patch_ref(cd, PATCHER_instanceof_interface,
+ patcher_add_patch_ref(jd, PATCHER_instanceof_interface,
iptr->sx.s23.s3.c.ref, 0);
}
if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
if (super == NULL) {
emit_label(cd, BRANCH_LABEL_2);
+
+ cr = iptr->sx.s23.s3.c.ref;
+ disp = dseg_add_unique_address(cd, cr);
+
+ patcher_add_patch_ref(jd,
+ PATCHER_resolve_classref_to_vftbl,
+ cr, disp);
}
else {
M_TEST(s1);
emit_label_beq(cd, BRANCH_LABEL_5);
- }
-
- M_ALD(REG_ITMP1, s1, OFFSET(java_object_t, vftbl));
- if (super == NULL) {
- codegen_add_patch_ref(cd, PATCHER_instanceof_class,
- iptr->sx.s23.s3.c.ref, 0);
+ disp = dseg_add_address(cd, super->vftbl);
}
- M_MOV_IMM(supervftbl, REG_ITMP2);
+ M_ALD(REG_ITMP1, s1, OFFSET(java_object_t, vftbl));
+ M_ALD(REG_ITMP2, RIP, disp);
CODEGEN_CRITICAL_SECTION_START;
}
}
+ /* a0 = dimension count */
+
+ M_MOV_IMM(iptr->s1.argcount, REG_A0);
+
/* is a patcher function set? */
if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
- codegen_add_patch_ref(cd, PATCHER_builtin_multianewarray,
- iptr->sx.s23.s3.c.ref, 0);
- }
-
- /* a0 = dimension count */
+ cr = iptr->sx.s23.s3.c.ref;
+ disp = dseg_add_unique_address(cd, cr);
- M_MOV_IMM(iptr->s1.argcount, REG_A0);
+ patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_classinfo,
+ cr, disp);
+ }
+ else {
+ disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
+ }
/* a1 = classinfo */
- M_MOV_IMM(iptr->sx.s23.s3.c.cls, REG_A1);
+ M_ALD(REG_A1, RIP, disp);
/* a2 = pointer to dimensions = stack pointer */
dseg_createlinenumbertable(cd);
- /* generate stubs */
+ /* Generate patcher traps. */
- emit_patcher_stubs(jd);
+ emit_patcher_traps(jd);
/* everything's ok */
/* code for the stub */
- M_ALD(REG_ITMP1, RIP, -(7 * 1 + 2 * SIZEOF_VOID_P)); /* methodinfo */
- M_ALD(REG_ITMP3, RIP, -(7 * 2 + 3 * SIZEOF_VOID_P)); /* compiler pointer */
+ M_LLD(REG_ITMP1, RIP, -(7 * 1 + 2 * SIZEOF_VOID_P)); /* methodinfo */
+/* M_ALD(REG_ITMP1, RIP, -(2 * SIZEOF_VOID_P)); /\* methodinfo *\/ */
+ M_LLD(REG_ITMP3, RIP, -(7 * 2 + 3 * SIZEOF_VOID_P)); /* compiler pointer */
+/* M_ALD(REG_ITMP3, RIP, -(3 * SIZEOF_VOID_P)); /\* compiler pointer *\/ */
M_JMP(REG_ITMP3);
}
s4 nativeparams;
s4 i, j;
s4 t;
- s4 s1, s2, disp;
+ s4 s1, s2;
+ int funcdisp;
+#if defined(ENABLE_GC_CACAO)
+ int disp;
+#endif
/* get required compiler data */
/* get function address (this must happen before the stackframeinfo) */
- if (f == NULL)
- codegen_add_patch_ref(cd, PATCHER_resolve_native, m, 0);
+ funcdisp = dseg_add_functionptr(cd, f);
- M_MOV_IMM(f, REG_ITMP3);
+ if (f == NULL)
+ patcher_add_patch_ref(jd, PATCHER_resolve_native_function, m, funcdisp);
#if defined(ENABLE_GC_CACAO)
/* Save callee saved integer registers in stackframeinfo (GC may
}
}
- M_AST(REG_ITMP3, REG_SP, md->paramcount * 8);
-
/* create dynamic stack info */
M_MOV(REG_SP, REG_A0);
}
}
- M_ALD(REG_ITMP3, REG_SP, md->paramcount * 8);
-
/* copy or spill arguments to new locations */
for (i = md->paramcount - 1, j = i + nativeparams; i >= 0; i--, j--) {
/* do the native function call */
- M_CALL(REG_ITMP3);
+ M_ALD(REG_ITMP1, RIP, funcdisp);
+ M_CALL(REG_ITMP1);
/* save return value */
M_MOV_IMM(asm_handle_nat_exception, REG_ITMP3);
M_JMP(REG_ITMP3);
- /* generate patcher stubs */
+ /* Generate patcher traps. */
- emit_patcher_stubs(jd);
+ emit_patcher_traps(jd);
}
/* patcher defines ************************************************************/
-#define PATCHER_CALL_SIZE 5 /* size in bytes of a patcher call */
+#define PATCHER_CALL_SIZE 2 /* size in bytes of a patcher call */
#define PATCHER_NOPS \
do { \
M_NOP; \
M_NOP; \
- M_NOP; \
- M_NOP; \
- M_NOP; \
} while (0)
#define M_IINC(a) emit_incl_reg(cd, (a))
#define M_IDEC(a) emit_decl_reg(cd, (a))
-#define M_ALD(a,b,disp) M_LLD(a,b,disp)
+#define M_ALD(a,b,disp) \
+ do { \
+ if (b == RIP) \
+ M_LLD(a, b, disp + -((cd->mcodeptr + 7) - cd->mcodebase)); \
+ else \
+ M_LLD(a, b, disp); \
+ } while (0)
+
#define M_ALD32(a,b,disp) M_LLD32(a,b,disp)
#define M_ALD_MEM(a,disp) emit_mov_mem_reg(cd, (disp), (a))
#include "vm/jit/codegen-common.h"
#include "vm/jit/emit-common.h"
#include "vm/jit/jit.h"
+#include "vm/jit/patcher-common.h"
#include "vm/jit/replace.h"
#include "vmcore/options.h"
}
-/* emit_patcher_stubs **********************************************************
-
- Generates the code for the patcher stubs.
-
-*******************************************************************************/
-
-void emit_patcher_stubs(jitdata *jd)
-{
- codegendata *cd;
- patchref *pref;
- u8 mcode;
- u1 *savedmcodeptr;
- u1 *tmpmcodeptr;
- s4 targetdisp;
- s4 disp;
-
- /* get required compiler data */
-
- cd = jd->cd;
-
- /* generate code patching stub call code */
-
- targetdisp = 0;
-
- for (pref = cd->patchrefs; pref != NULL; pref = pref->next) {
- /* check size of code segment */
-
- MCODECHECK(512);
-
- /* Get machine code which is patched back in later. A
- `call rel32' is 5 bytes long (but read 8 bytes). */
-
- savedmcodeptr = cd->mcodebase + pref->branchpos;
- mcode = *((u8 *) savedmcodeptr);
-
- /* patch in `call rel32' to call the following code */
-
- tmpmcodeptr = cd->mcodeptr; /* save current mcodeptr */
- cd->mcodeptr = savedmcodeptr; /* set mcodeptr to patch position */
-
- M_CALL_IMM(tmpmcodeptr - (savedmcodeptr + PATCHER_CALL_SIZE));
-
- cd->mcodeptr = tmpmcodeptr; /* restore the current mcodeptr */
-
- /* move pointer to java_objectheader onto stack */
-
-#if defined(ENABLE_THREADS)
- /* create a virtual java_objectheader */
-
- (void) dseg_add_unique_address(cd, NULL); /* flcword */
- (void) dseg_add_unique_address(cd, lock_get_initial_lock_word());
- disp = dseg_add_unique_address(cd, NULL); /* vftbl */
-
- emit_lea_membase_reg(cd, RIP, -((cd->mcodeptr + 7) - cd->mcodebase) + disp, REG_ITMP3);
- M_PUSH(REG_ITMP3);
-#else
- M_PUSH_IMM(0);
-#endif
-
- /* move machine code bytes and classinfo pointer into registers */
-
- M_MOV_IMM(mcode, REG_ITMP3);
- M_PUSH(REG_ITMP3);
-
- M_MOV_IMM(pref->ref, REG_ITMP3);
- M_PUSH(REG_ITMP3);
-
- M_MOV_IMM(pref->disp, REG_ITMP3);
- M_PUSH(REG_ITMP3);
-
- M_MOV_IMM(pref->patcher, REG_ITMP3);
- M_PUSH(REG_ITMP3);
-
- if (targetdisp == 0) {
- targetdisp = cd->mcodeptr - cd->mcodebase;
-
- M_MOV_IMM(asm_patcher_wrapper, REG_ITMP3);
- M_JMP(REG_ITMP3);
- }
- else {
- M_JMP_IMM((cd->mcodebase + targetdisp) -
- (cd->mcodeptr + PATCHER_CALL_SIZE));
- }
- }
-}
-
-
/* emit_trap *******************************************************************
Emit a trap instruction and return the original machine code.
uint32_t emit_trap(codegendata *cd)
{
- uint32_t mcode;
+ uint16_t mcode;
- /* Get machine code which is patched back in later. The
- trap is 1 instruction word long. */
+ /* Get machine code which is patched back in later. The trap is 2
+ bytes long. */
- mcode = *((uint32_t *) cd->mcodeptr);
+ mcode = *((uint16_t *) cd->mcodeptr);
- M_NOP;
+ /* XXX This needs to be change to INT3 when the debugging problems
+ with gdb are resolved. */
+
+ M_UD2;
return mcode;
}
}
+/* md_signal_handler_sigill ****************************************************
+
+ Signal handler for patchers.
+
+*******************************************************************************/
+
+void md_signal_handler_sigill(int sig, siginfo_t *siginfo, void *_p)
+{
+ stackframeinfo sfi;
+ ucontext_t *_uc;
+ mcontext_t *_mc;
+ u1 *pv;
+ u1 *sp;
+ u1 *ra;
+ u1 *xpc;
+ int type;
+ intptr_t val;
+ void *p;
+
+ _uc = (ucontext_t *) _p;
+ _mc = &_uc->uc_mcontext;
+
+ /* ATTENTION: Don't use CACAO's internal REG_* defines as they are
+ different to the ones in <ucontext.h>. */
+
+ pv = NULL;
+ sp = (u1 *) _mc->gregs[REG_RSP];
+ xpc = (u1 *) _mc->gregs[REG_RIP];
+ ra = xpc; /* return address is equal to xpc */
+
+ /* This is a patcher. */
+
+ type = EXCEPTION_HARDWARE_PATCHER;
+ val = 0;
+
+ /* create stackframeinfo */
+
+ stacktrace_create_extern_stackframeinfo(&sfi, pv, sp, ra, xpc);
+
+ /* Handle the type. */
+
+ p = signal_handle(xpc, type, val);
+
+ /* remove stackframeinfo */
+
+ stacktrace_remove_stackframeinfo(&sfi);
+
+ /* set registers */
+
+ if (p != NULL) {
+ _mc->gregs[REG_RAX] = (intptr_t) p;
+ _mc->gregs[REG_R10] = (intptr_t) xpc; /* REG_ITMP2_XPC */
+ _mc->gregs[REG_RIP] = (intptr_t) asm_handle_exception;
+ }
+}
+
+
/* md_signal_handler_sigusr1 ***************************************************
Signal handler for suspending threads.
#include "vm/exceptions.h"
#include "vm/initialize.h"
-#include "vm/jit/patcher.h"
+#include "vm/jit/patcher-common.h"
#include "vm/jit/stacktrace.h"
#include "vmcore/class.h"
#include "vm/resolve.h"
-/* patcher_wrapper *************************************************************
+#define PATCH_BACK_ORIGINAL_MCODE \
+ do { \
+ *((uint16_t *) pr->mpc) = (uint16_t) pr->mcode; \
+ } while (0)
- Wrapper for all patchers. It also creates the stackframe info
- structure.
- If the return value of the patcher function is false, it gets the
- exception object, clears the exception pointer and returns the
- exception.
+/* patcher_patch_code **********************************************************
+
+ Just patches back the original machine code.
*******************************************************************************/
-java_object_t *patcher_wrapper(u1 *sp, u1 *pv, u1 *ra)
+void patcher_patch_code(patchref_t *pr)
{
- stackframeinfo sfi;
- u1 *xpc;
- java_object_t *o;
- functionptr f;
- bool result;
- java_handle_t *e;
+ PATCH_BACK_ORIGINAL_MCODE;
+}
+
+
+/* patcher_resolve_classref_to_classinfo ***************************************
+
+ ACONST:
+
+ <patched call position>
+ 48 bf a0 f0 92 00 00 00 00 00 mov $0x92f0a0,%rdi
+
+ MULTIANEWARRAY:
+
+ <patched call position>
+ 48 be 30 40 b2 00 00 00 00 00 mov $0xb24030,%rsi
+ 48 89 e2 mov %rsp,%rdx
+ 48 b8 7c 96 4b 00 00 00 00 00 mov $0x4b967c,%rax
+ 48 ff d0 callq *%rax
- /* define the patcher function */
+ ARRAYCHECKCAST:
+
+ <patched call position>
+ 48 be b8 3f b2 00 00 00 00 00 mov $0xb23fb8,%rsi
+ 48 b8 00 00 00 00 00 00 00 00 mov $0x0,%rax
+ 48 ff d0 callq *%rax
+
+*******************************************************************************/
+
+bool patcher_resolve_classref_to_classinfo(patchref_t *pr)
+{
+ constant_classref *cr;
+ intptr_t *datap;
+ classinfo *c;
- bool (*patcher_function)(u1 *);
+ cr = (constant_classref *) pr->ref;
+ datap = (intptr_t *) pr->datap;
+
+ /* get the classinfo */
+
+ if (!(c = resolve_classref_eager(cr)))
+ return false;
+
+ PATCH_BACK_ORIGINAL_MCODE;
+
+ /* patch the classinfo pointer */
+
+ *datap = (intptr_t) c;
+
+ return true;
+}
+
+
+/* patcher_resolve_classref_to_vftbl *******************************************
+
+ CHECKCAST (class):
+ INSTANCEOF (class):
+
+ <patched call position>
+
+*******************************************************************************/
+
+bool patcher_resolve_classref_to_vftbl(patchref_t *pr)
+{
+ constant_classref *cr;
+ intptr_t *datap;
+ classinfo *c;
/* get stuff from the stack */
- xpc = (u1 *) *((ptrint *) (sp + 5 * 8));
- o = (java_object_t *) *((ptrint *) (sp + 4 * 8));
- f = (functionptr) *((ptrint *) (sp + 0 * 8));
+ cr = (constant_classref *) pr->ref;
+ datap = (intptr_t *) pr->datap;
+
+ /* get the fieldinfo */
+
+ if (!(c = resolve_classref_eager(cr)))
+ return false;
- /* calculate and set the new return address */
+ PATCH_BACK_ORIGINAL_MCODE;
- xpc = xpc - PATCHER_CALL_SIZE;
+ /* patch super class' vftbl */
- *((ptrint *) (sp + 5 * 8)) = (ptrint) xpc;
+ *datap = (intptr_t) c->vftbl;
+
+ return true;
+}
- /* cast the passed function to a patcher function */
- patcher_function = (bool (*)(u1 *)) (ptrint) f;
+/* patcher_resolve_classref_to_flags *******************************************
- /* enter a monitor on the patching position */
+ CHECKCAST/INSTANCEOF:
+
+ <patched call position>
+
+*******************************************************************************/
+
+bool patcher_resolve_classref_to_flags(patchref_t *pr)
+{
+ constant_classref *cr;
+ int32_t *datap;
+ classinfo *c;
+ uint8_t *ra;
- PATCHER_MONITORENTER;
+ cr = (constant_classref *) pr->ref;
+ datap = (int32_t *) pr->datap;
+ ra = (uint8_t *) pr->mpc;
- /* create the stackframeinfo */
+ /* get the fieldinfo */
- /* RA is passed as NULL, but the XPC is correct and can be used in
- stacktrace_create_extern_stackframeinfo for
- md_codegen_get_pv_from_pc. */
+ if (!(c = resolve_classref_eager(cr)))
+ return false;
- stacktrace_create_extern_stackframeinfo(&sfi, pv, sp + 6 * 8, xpc, xpc);
+ PATCH_BACK_ORIGINAL_MCODE;
- /* call the proper patcher function */
+ /* if we show disassembly, we have to skip the nop's */
- result = (patcher_function)(sp);
+ if (opt_shownops)
+ ra = ra + PATCHER_CALL_SIZE;
- /* remove the stackframeinfo */
+ /* patch class flags */
- stacktrace_remove_stackframeinfo(&sfi);
+/* *datap = c->flags; */
+ *((int32_t *) (ra + 2)) = c->flags;
- /* check for return value and exit accordingly */
+ return true;
+}
- if (result == false) {
- e = exceptions_get_and_clear_exception();
- PATCHER_MONITOREXIT;
+/* patcher_resolve_native_function *********************************************
- return e;
- }
+ XXX
- PATCHER_MARK_PATCHED_MONITOREXIT;
+*******************************************************************************/
- return NULL;
+bool patcher_resolve_native_function(patchref_t *pr)
+{
+ methodinfo *m;
+ intptr_t *datap;
+ functionptr f;
+
+ m = (methodinfo *) pr->ref;
+ datap = (intptr_t *) pr->datap;
+
+ /* resolve native function */
+
+ if (!(f = native_resolve_function(m)))
+ return false;
+
+ PATCH_BACK_ORIGINAL_MCODE;
+
+ /* patch native function pointer */
+
+ *datap = (intptr_t) f;
+
+ return true;
}
*******************************************************************************/
-bool patcher_get_putstatic(u1 *sp)
+bool patcher_get_putstatic(patchref_t *pr)
{
- u1 *ra;
- u8 mcode;
unresolved_field *uf;
- s4 disp;
+ intptr_t *datap;
fieldinfo *fi;
- /* get stuff from the stack */
-
- ra = (u1 *) *((ptrint *) (sp + 5 * 8));
- mcode = *((u8 *) (sp + 3 * 8));
- uf = (unresolved_field *) *((ptrint *) (sp + 2 * 8));
- disp = *((s4 *) (sp + 1 * 8));
+ uf = (unresolved_field *) pr->ref;
+ datap = (intptr_t *) pr->datap;
/* get the fieldinfo */
if (!initialize_class(fi->class))
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 + 5;
+ PATCH_BACK_ORIGINAL_MCODE;
/* patch the field value's address */
- *((intptr_t *) (ra + 7 + disp)) = (intptr_t) fi->value;
+ *datap = (intptr_t) fi->value;
return true;
}
*******************************************************************************/
-bool patcher_get_putfield(u1 *sp)
+bool patcher_get_putfield(patchref_t *pr)
{
- u1 *ra;
- u8 mcode;
+ uint8_t *ra;
unresolved_field *uf;
fieldinfo *fi;
- u1 byte;
+ uint8_t byte;
- /* get stuff from the stack */
-
- ra = (u1 *) *((ptrint *) (sp + 5 * 8));
- mcode = *((u8 *) (sp + 3 * 8));
- uf = (unresolved_field *) *((ptrint *) (sp + 2 * 8));
+ ra = (uint8_t *) pr->mpc;
+ uf = (unresolved_field *) pr->ref;
/* get the fieldinfo */
if (!(fi = resolve_field_eager(uf)))
return false;
- /* patch back original code (instruction code is smaller than 8 bytes) */
-
- *((u4 *) (ra + 0)) = (u4) mcode;
- *((u1 *) (ra + 4)) = (u1) (mcode >> 32);
+ PATCH_BACK_ORIGINAL_MCODE;
/* if we show disassembly, we have to skip the nop's */
if (opt_shownops)
- ra = ra + 5;
+ ra = ra + PATCHER_CALL_SIZE;
- /* patch the field's offset: we check for the field type, because the */
- /* instructions have different lengths */
+ /* Patch the field's offset: we check for the field type, because
+ the instructions have different lengths. */
if (IS_INT_LNG_TYPE(fi->type)) {
- /* check for special case: %rsp or %r12 as base register */
+ /* Check for special case: %rsp or %r12 as base register. */
byte = *(ra + 3);
*((int32_t *) (ra + 3)) = fi->offset;
}
else {
- /* check for special case: %rsp or %r12 as base register */
+ /* Check for special case: %rsp or %r12 as base register. */
byte = *(ra + 5);
*******************************************************************************/
-bool patcher_putfieldconst(u1 *sp)
+bool patcher_putfieldconst(patchref_t *pr)
{
- u1 *ra;
- u8 mcode;
+ uint8_t *ra;
unresolved_field *uf;
fieldinfo *fi;
+ uint8_t byte;
- /* get stuff from the stack */
-
- ra = (u1 *) *((ptrint *) (sp + 5 * 8));
- mcode = *((u8 *) (sp + 3 * 8));
- uf = (unresolved_field *) *((ptrint *) (sp + 2 * 8));
+ ra = (uint8_t *) pr->mpc;
+ uf = (unresolved_field *) pr->ref;
/* get the fieldinfo */
if (!(fi = resolve_field_eager(uf)))
return false;
- /* patch back original code */
-
- *((u8 *) ra) = mcode;
+ PATCH_BACK_ORIGINAL_MCODE;
/* if we show disassembly, we have to skip the nop's */
if (opt_shownops)
- ra = ra + 5;
+ ra = ra + PATCHER_CALL_SIZE;
/* patch the field's offset */
if (IS_2_WORD_TYPE(fi->type) || IS_ADR_TYPE(fi->type)) {
/* handle special case when the base register is %r12 */
- if (*(ra + 2) == 0x84) {
+ byte = *(ra + 2);
+
+ if (byte == 0x84) {
*((uint32_t *) (ra + 4)) = fi->offset;
*((uint32_t *) (ra + 12 + 4)) = fi->offset + 4;
}
else {
/* handle special case when the base register is %r12 */
- if (*(ra + 2) == 0x84)
+ byte = *(ra + 2);
+
+ if (byte == 0x84)
*((uint32_t *) (ra + 4)) = fi->offset;
else
*((uint32_t *) (ra + 3)) = fi->offset;
}
-/* patcher_aconst **************************************************************
-
- Machine code:
-
- <patched call position>
- 48 bf a0 f0 92 00 00 00 00 00 mov $0x92f0a0,%rdi
-
-*******************************************************************************/
-
-bool patcher_aconst(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 classinfo */
-
- 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 + 5;
-
- /* patch the classinfo pointer */
-
- *((ptrint *) (ra + 2)) = (ptrint) c;
-
- return true;
-}
-
-
-/* patcher_builtin_multianewarray **********************************************
-
- Machine code:
-
- <patched call position>
- 48 bf 02 00 00 00 00 00 00 00 mov $0x2,%rdi
- 48 be 30 40 b2 00 00 00 00 00 mov $0xb24030,%rsi
- 48 89 e2 mov %rsp,%rdx
- 48 b8 7c 96 4b 00 00 00 00 00 mov $0x4b967c,%rax
- 48 ff d0 callq *%rax
-
-*******************************************************************************/
-
-bool patcher_builtin_multianewarray(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 classinfo */
-
- 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 + 5;
-
- /* patch the classinfo pointer */
-
- *((ptrint *) (ra + 10 + 2)) = (ptrint) c;
-
- return true;
-}
-
-
-/* patcher_builtin_arraycheckcast **********************************************
-
- Machine code:
-
- <patched call position>
- 48 be b8 3f b2 00 00 00 00 00 mov $0xb23fb8,%rsi
- 48 b8 00 00 00 00 00 00 00 00 mov $0x0,%rax
- 48 ff d0 callq *%rax
-
-*******************************************************************************/
-
-bool patcher_builtin_arraycheckcast(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 classinfo */
-
- 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 + 5;
-
- /* patch the classinfo pointer */
-
- *((ptrint *) (ra + 2)) = (ptrint) c;
-
- return true;
-}
-
-
/* patcher_invokestatic_special ************************************************
Machine code:
*******************************************************************************/
-bool patcher_invokestatic_special(u1 *sp)
+bool patcher_invokestatic_special(patchref_t *pr)
{
- u1 *ra;
- u8 mcode;
unresolved_method *um;
- s4 disp;
+ intptr_t *datap;
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));
+ um = (unresolved_method *) pr->ref;
+ datap = (intptr_t *) pr->datap;
/* get the fieldinfo */
if (!(m = resolve_method_eager(um)))
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_BACK_ORIGINAL_MCODE;
/* patch stubroutine */
-/* *((ptrint *) (ra + 2)) = (ptrint) m->stubroutine; */
- *((ptrint *) (ra + 7 + disp)) = (ptrint) m->stubroutine;
+ *datap = (intptr_t) m->stubroutine;
return true;
}
*******************************************************************************/
-bool patcher_invokevirtual(u1 *sp)
+bool patcher_invokevirtual(patchref_t *pr)
{
- u1 *ra;
- u8 mcode;
+ uint8_t *ra;
unresolved_method *um;
methodinfo *m;
- /* get stuff from the stack */
+ ra = (uint8_t *) pr->mpc;
+ um = (unresolved_method *) pr->ref;
- ra = (u1 *) *((ptrint *) (sp + 5 * 8));
- mcode = *((u8 *) (sp + 3 * 8));
- um = (unresolved_method *) *((ptrint *) (sp + 2 * 8));
-
- /* get the fieldinfo */
+ /* get the methodinfo */
if (!(m = resolve_method_eager(um)))
return false;
- /* patch back original code */
-
- *((u8 *) ra) = mcode;
+ PATCH_BACK_ORIGINAL_MCODE;
/* if we show disassembly, we have to skip the nop's */
if (opt_shownops)
- ra = ra + 5;
+ ra = ra + PATCHER_CALL_SIZE;
/* patch vftbl index */
- *((s4 *) (ra + 3 + 3)) = (s4) (OFFSET(vftbl_t, table[0]) +
- sizeof(methodptr) * m->vftblindex);
+ *((int32_t *) (ra + 3 + 3)) =
+ (int32_t) (OFFSET(vftbl_t, table[0]) +
+ sizeof(methodptr) * m->vftblindex);
return true;
}
*******************************************************************************/
-bool patcher_invokeinterface(u1 *sp)
+bool patcher_invokeinterface(patchref_t *pr)
{
- u1 *ra;
- u8 mcode;
+ uint8_t *ra;
unresolved_method *um;
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));
+ ra = (uint8_t *) pr->mpc;
+ um = (unresolved_method *) pr->ref;
/* get the fieldinfo */
if (!(m = resolve_method_eager(um)))
return false;
- /* patch back original code */
-
- *((u8 *) ra) = mcode;
+ PATCH_BACK_ORIGINAL_MCODE;
/* if we show disassembly, we have to skip the nop's */
if (opt_shownops)
- ra = ra + 5;
+ ra = ra + PATCHER_CALL_SIZE;
/* patch interfacetable index */
- *((s4 *) (ra + 3 + 3)) = (s4) (OFFSET(vftbl_t, interfacetable[0]) -
- sizeof(methodptr) * m->class->index);
+ *((int32_t *) (ra + 3 + 3)) =
+ (int32_t) (OFFSET(vftbl_t, interfacetable[0]) -
+ sizeof(methodptr) * m->class->index);
/* patch method offset */
- *((s4 *) (ra + 3 + 7 + 3)) =
- (s4) (sizeof(methodptr) * (m - m->class->methods));
-
- return true;
-}
-
-
-/* patcher_checkcast_instanceof_flags ******************************************
-
- Machine code:
-
- <patched call position>
- 41 ba 00 00 00 00 mov $0x0,%r10d
- 41 81 e2 00 02 00 00 and $0x200,%r10d
- 0f 84 35 00 00 00 je 0x00002aaaaab01479
-
-*******************************************************************************/
-
-bool patcher_checkcast_instanceof_flags(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 + 5;
-
- /* patch class flags */
-
- *((s4 *) (ra + 2)) = (s4) c->flags;
+ *((int32_t *) (ra + 3 + 7 + 3)) =
+ (int32_t) (sizeof(methodptr) * (m - m->class->methods));
return true;
}
*******************************************************************************/
-bool patcher_checkcast_interface(u1 *sp)
+bool patcher_checkcast_interface(patchref_t *pr)
{
- u1 *ra;
- u8 mcode;
+ uint8_t *ra;
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));
+ ra = (uint8_t *) pr->mpc;
+ cr = (constant_classref *) pr->ref;
/* get the fieldinfo */
if (!(c = resolve_classref_eager(cr)))
return false;
- /* patch back original code */
-
- *((u8 *) ra) = mcode;
+ PATCH_BACK_ORIGINAL_MCODE;
/* if we show disassembly, we have to skip the nop's */
/* patch super class index */
- *((s4 *) (ra + 7 + 3)) = (s4) c->index;
+ *((int32_t *) (ra + 7 + 3)) = c->index;
- *((s4 *) (ra + 7 + 7 + 6 + 8 + 3)) =
- (s4) (OFFSET(vftbl_t, interfacetable[0]) -
- c->index * sizeof(methodptr*));
-
- return true;
-}
-
-
-/* patcher_checkcast_class *****************************************************
-
- Machine code:
-
- <patched call position>
- 49 bb 00 00 00 00 00 00 00 00 mov $0x0,%r11
- 45 8b 92 20 00 00 00 mov 0x20(%r10),%r10d
- 45 8b 9b 20 00 00 00 mov 0x20(%r11),%r11d
- 4d 29 da sub %r11,%r10
- 49 bb 00 00 00 00 00 00 00 00 mov $0x0,%r11
-
-*******************************************************************************/
-
-bool patcher_checkcast_class(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 + 5;
-
- /* patch super class' vftbl */
-
- *((ptrint *) (ra + 2)) = (ptrint) c->vftbl;
- *((ptrint *) (ra + 10 + 7 + 7 + 3 + 2)) = (ptrint) c->vftbl;
+ *((int32_t *) (ra + 7 + 7 + 6 + 8 + 3)) =
+ (int32_t) (OFFSET(vftbl_t, interfacetable[0]) -
+ c->index * sizeof(methodptr*));
return true;
}
*******************************************************************************/
-bool patcher_instanceof_interface(u1 *sp)
+bool patcher_instanceof_interface(patchref_t *pr)
{
- u1 *ra;
- u8 mcode;
+ uint8_t *ra;
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));
+ ra = (uint8_t *) pr->mpc;
+ cr = (constant_classref *) pr->ref;
/* get the fieldinfo */
if (!(c = resolve_classref_eager(cr)))
return false;
- /* patch back original code */
-
- *((u8 *) ra) = mcode;
+ PATCH_BACK_ORIGINAL_MCODE;
/* if we show disassembly, we have to skip the nop's */
/* 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:
-
- <patched call position>
- 49 ba 00 00 00 00 00 00 00 00 mov $0x0,%r10
-
-*******************************************************************************/
-
-bool patcher_instanceof_class(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 + 5;
-
- /* patch super class' vftbl */
-
- *((ptrint *) (ra + 2)) = (ptrint) c->vftbl;
-
- return true;
-}
-
-
-/* patcher_clinit **************************************************************
-
- May be used for GET/PUTSTATIC and in native stub.
-
- Machine code:
-
- <patched call position>
- 4d 8b 15 92 ff ff ff mov -110(%rip),%r10
- 49 89 1a mov %rbx,(%r10)
-
-*******************************************************************************/
-
-bool patcher_clinit(u1 *sp)
-{
- u1 *ra;
- u8 mcode;
- classinfo *c;
-
- /* get stuff from the stack */
-
- ra = (u1 *) *((ptrint *) (sp + 5 * 8));
- mcode = *((u8 *) (sp + 3 * 8));
- c = (classinfo *) *((ptrint *) (sp + 2 * 8));
-
- /* check if the class is initialized */
-
- if (!(c->state & CLASS_INITIALIZED))
- if (!initialize_class(c))
- return false;
-
- /* patch back original code */
-
- *((u8 *) ra) = mcode;
-
- return true;
-}
-
-
-/* patcher_athrow_areturn ******************************************************
-
- Machine code:
-
- <patched call position>
-
-*******************************************************************************/
-
-#ifdef ENABLE_VERIFIER
-bool patcher_athrow_areturn(u1 *sp)
-{
- u1 *ra;
- u8 mcode;
- unresolved_class *uc;
-
- /* get stuff from the stack */
-
- ra = (u1 *) *((ptrint *) (sp + 5 * 8));
- mcode = *((u8 *) (sp + 3 * 8));
- uc = (unresolved_class *) *((ptrint *) (sp + 2 * 8));
-
- /* resolve the class and check subtype constraints */
-
- if (!resolve_class_eager_no_access_check(uc))
- return false;
-
- /* patch back original code */
-
- *((u8 *) ra) = mcode;
-
- return true;
-}
-#endif /* ENABLE_VERIFIER */
-
-
-/* patcher_resolve_native ******************************************************
-
- Machine code:
-
- <patched call position>
- 48 b8 00 00 00 00 00 00 00 00 mov $0x0,%rax
- 48 ff d0 callq *%rax
-
-*******************************************************************************/
-
-bool patcher_resolve_native(u1 *sp)
-{
- u1 *ra;
- u8 mcode;
- methodinfo *m;
- functionptr f;
-
- /* get stuff from the stack */
-
- ra = (u1 *) *((ptrint *) (sp + 5 * 8));
- mcode = *((u8 *) (sp + 3 * 8));
- m = (methodinfo *) *((ptrint *) (sp + 2 * 8));
-
- /* resolve native function */
-
- if (!(f = native_resolve_function(m)))
- 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 + 5;
-
- /* patch native function pointer */
+ *((int32_t *) (ra + 7 + 3)) = c->index;
- *((ptrint *) (ra + 2)) = (ptrint) f;
+ *((int32_t *) (ra + 7 + 7 + 6 + 3)) =
+ (int32_t) (OFFSET(vftbl_t, interfacetable[0]) -
+ c->index * sizeof(methodptr*));
return true;
}
SA_NODEFER | SA_SIGINFO);
# endif
-# if defined(__ARM__) || defined(__I386__) || defined(__S390__)
+# if defined(__ARM__) || defined(__I386__) || defined(__S390__) || defined(__X86_64__)
/* XXX use better defines for that (in arch.h) */
/* SIGILL handler */
void md_signal_handler_sigfpe(int sig, siginfo_t *siginfo, void *_p);
#endif
-#if defined(__ARM__) || defined(__I386__) || defined(__S390__)
+#if defined(__ARM__) || defined(__I386__) || defined(__S390__) || defined(__X86_64__)
/* XXX use better defines for that (in arch.h) */
void md_signal_handler_sigill(int sig, siginfo_t *siginfo, void *_p);
#endif