Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA.
- $Id: patcher.c 7311 2007-02-09 13:20:27Z twisti $
-
*/
#include "config.h"
#include <assert.h>
+#include <stdint.h>
#include "vm/types.h"
#include "mm/memory.h"
+
#include "native/native.h"
#include "vm/builtin.h"
#include "vm/initialize.h"
#include "vm/jit/asmpart.h"
-#include "vm/jit/patcher.h"
#include "vm/jit/md.h"
#include "vm/jit/methodheader.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 "vmcore/resolve.h"
+#include "vm/resolve.h"
/* patcher_wrapper *************************************************************
/* patch the field value's address */
- *((ptrint *) (pv + disp)) = (ptrint) &(fi->value);
+ *((intptr_t *) (pv + disp)) = (intptr_t) fi->value;
/* synchronize data cache */
/* if we show disassembly, we have to skip the nop */
- if (opt_showdisassemble)
+ if (opt_shownops)
ra = ra + 4;
/* patch the field's offset */
/* if we show disassembly, we have to skip the nop */
- if (opt_showdisassemble)
+ if (opt_shownops)
ra = ra + 4;
/* patch vftbl index */
/* if we show disassembly, we have to skip the nop */
- if (opt_showdisassemble)
+ if (opt_shownops)
ra = ra + 4;
/* patch interfacetable index */
return true;
}
+/* patcher_checkcast_interface **************************************
+
+ Machine code:
+
+ <patched call position>
+ 81870000 lwz r12,0(r7)
+ 800c0010 lwz r0,16(r12)
+ 34000000 addic. r0,r0,0
+ 408101fc bgt- 0x3002e518 FIXME
+ 83c00003 lwz r30,3(0) FIXME
+ 800c0000 lwz r0,0(r12)
+
+*******************************************************************************/
+bool patcher_checkcast_interface(u1 *sp)
+{
+ u1 *ra;
+ constant_classref *cr;
+ classinfo *c;
+ s4 disp;
+ u4 mcode;
+
+ /* get stuff from stack */
+ ra = (u1*) *((ptrint *)(sp + 5*8));
+ mcode = *((u4*) (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 */
+ *((u4 *) ra) = mcode;
+
+ /* if we show NOPs, we have to skip them */
+ if (opt_shownops) {
+ ra = ra +4;
+ }
+
+ /* patch super class index */
+ disp = -(c->index);
+
+ *((s4*)(ra + 2*4)) |= (disp & 0x0000ffff);
+
+ disp = OFFSET(vftbl_t, interfacetable[0]) - c->index * sizeof(methodptr*);
+
+ *((s4 *)(ra + 5*4)) |= (disp & 0x0000ffff);
+
+ /* sync instruction cache */
+ md_icacheflush(ra, 6*4);
+
+ return true;
+}
-/* patcher_checkcast_instanceof_interface **************************************
+/* patcher_instanceof_interface **************************************
Machine code:
*******************************************************************************/
-bool patcher_checkcast_instanceof_interface(u1 *sp)
+bool patcher_instanceof_interface(u1 *sp)
{
u1 *ra;
u4 mcode;
/* if we show disassembly, we have to skip the nop */
- if (opt_showdisassemble)
+ if (opt_shownops)
ra = ra + 4;
/* patch super class index */
return true;
}
+/* patcher_resolve_classref_to_classinfo ***************************************
+
+ ACONST:
+
+ <patched call postition>
+ 806dffc4 lwz r3,-60(r13)
+ 81adffc0 lwz r13,-64(r13)
+ 7da903a6 mtctr r13
+ 4e800421 bctrl
+
+
+ MULTIANEWARRAY:
+
+ <patched call position>
+ 808dffc0 lwz r4,-64(r13)
+ 38a10038 addi r5,r1,56
+ 81adffbc lwz r13,-68(r13)
+ 7da903a6 mtctr r13
+ 4e800421 bctrl
+
+
+ ARRAYCHECKCAST:
+
+ <patched call position>
+ 808dffd8 lwz r4,-40(r13)
+ 81adffd4 lwz r13,-44(r13)
+ 7da903a6 mtctr r13
+ 4e800421 bctrl
+
+*******************************************************************************/
+
+bool patcher_resolve_classref_to_classinfo(u1 *sp)
+{
+ constant_classref *cr;
+ s4 disp;
+ u1 *pv, *ra;
+ u4 mcode;
+ classinfo *c;
+
+ /* get stuff from the stack */
+
+ ra = (u1 *) *((ptrint *) (sp + 5 * 8));
+ mcode = *((u4 *) (sp + 3 * 8));
+ cr = (constant_classref *) *((ptrint *) (sp + 2 * 8));
+ disp = *((s4 *) (sp + 1 * 8));
+ pv = (u1 *) *((ptrint *) (sp + 0 * 8));
+
+ /* get the classinfo */
+
+ if (!(c = resolve_classref_eager(cr)))
+ return false;
+
+ /* patch back original code */
+
+ *((u4 *) ra) = mcode;
+
+ /* synchronize instruction cache */
+
+ md_icacheflush(ra, 4);
+
+ /* patch the classinfo pointer */
+
+ *((ptrint *) (pv + disp)) = (ptrint) c;
+
+ /* synchronize data cache */
+
+ md_dcacheflush(pv + disp, SIZEOF_VOID_P);
+
+ return true;
+}
+
+
/* patcher_instanceof_class ****************************************************
return true;
}
+/* patcher_resolve_classref_to_vftbl *******************************************
+
+ CHECKCAST (class):
+
+ <patched call position>
+ 81870000 lwz r12,0(r7)
+ 800c0014 lwz r0,20(r12)
+ 818dff78 lwz r12,-136(r13)
+
+
+ INSTANCEOF (class):
+
+ <patched call position>
+ 817d0000 lwz r11,0(r29)
+ 818dff8c lwz r12,-116(r13)
+
+*******************************************************************************/
+
+bool patcher_resolve_classref_to_vftbl(u1 *sp)
+{
+ constant_classref *cr;
+ s4 disp;
+ u1 *pv, *ra;
+ u4 mcode;
+ classinfo *c;
+
+ /* get stuff from the stack */
+
+ ra = (u1 *) *((ptrint *) (sp + 5 * 8));
+ mcode = *((u4 *) (sp + 3 * 8));
+ cr = (constant_classref *) *((ptrint *) (sp + 2 * 8));
+ disp = *((s4 *) (sp + 1 * 8));
+ pv = (u1 *) *((ptrint *) (sp + 0 * 8));
+
+ /* get the fieldinfo */
+
+ if (!(c = resolve_classref_eager(cr)))
+ return false;
+
+ /* patch back original code */
+
+ *((u4 *) ra) = mcode;
+
+ /* synchronize instruction cache */
+
+ md_icacheflush(ra, 4);
+
+ /* patch super class' vftbl */
+
+ *((ptrint *) (pv + disp)) = (ptrint) c->vftbl;
+
+ /* synchronize data cache */
+
+ md_dcacheflush(pv + disp, SIZEOF_VOID_P);
+
+ return true;
+}
+
+/* patcher_resolve_classref_to_flags *******************************************
+
+ CHECKCAST/INSTANCEOF:
+
+ <patched call position>
+ 818dff7c lwz r12,-132(r13)
+
+*******************************************************************************/
+
+bool patcher_resolve_classref_to_flags(u1 *sp)
+{
+ constant_classref *cr;
+ s4 disp;
+ u1 *pv, *ra;
+ u4 mcode;
+ classinfo *c;
+
+ /* get stuff from the stack */
+
+ ra = (u1 *) *((ptrint *) (sp + 5 * 8));
+ mcode = *((u4 *) (sp + 3 * 8));
+ cr = (constant_classref *) *((ptrint *) (sp + 2 * 8));
+ disp = *((s4 *) (sp + 1 * 8));
+ pv = (u1 *) *((ptrint *) (sp + 0 * 8));
+
+ /* get the fieldinfo */
+
+ if (!(c = resolve_classref_eager(cr)))
+ return false;
+
+ /* patch back original code */
+
+ *((u4 *) ra) = mcode;
+
+ /* synchronize instruction cache */
+
+ md_icacheflush(ra, 4);
+
+ /* patch class flags */
+
+ *((s4 *) (pv + disp)) = (s4) c->flags;
+
+ /* synchronize data cache */
+
+ md_dcacheflush(pv + disp, SIZEOF_VOID_P);
+
+ return true;
+}
/* patcher_clinit **************************************************************
u1 *ra;
u4 mcode;
unresolved_class *uc;
- classinfo *c;
/* get stuff from the stack */
mcode = *((u4 *) (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 */
disp = *((s4 *) (sp + 1 * 8));
pv = (u1 *) *((ptrint *) (sp + 0 * 8));
- /* calculate and set the new return address */
-
- ra = ra - 1 * 4;
- *((ptrint *) (sp + 5 * 8)) = (ptrint) ra;
-
/* resolve native function */
if (!(f = native_resolve_function(m)))