X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=src%2Fvm%2Fjit%2Fmips%2Fpatcher.c;h=703ee87695d84a25916d608eb541315712b6d1aa;hb=9f859ad50d3d5d98c185d40b86b2179bc4dc9aeb;hp=6ea73649dc497ac38ebeabf04a6bc8b973d0dee1;hpb=3d884b5ec88870e3619811393839fc7b09eada33;p=cacao.git diff --git a/src/vm/jit/mips/patcher.c b/src/vm/jit/mips/patcher.c index 6ea73649d..703ee8769 100644 --- a/src/vm/jit/mips/patcher.c +++ b/src/vm/jit/mips/patcher.c @@ -1,9 +1,9 @@ /* src/vm/jit/mips/patcher.c - MIPS code patching functions - Copyright (C) 1996-2005 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 + 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 This file is part of CACAO. @@ -19,613 +19,377 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - 02111-1307, USA. - - Contact: cacao@complang.tuwien.ac.at - - Authors: Christian Thalinger - - Changes: - - $Id: patcher.c 3518 2005-10-28 14:47:11Z twisti $ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301, USA. */ -#include - #include "config.h" + +#include +#include + #include "vm/types.h" +#include "vm/jit/mips/codegen.h" + #include "mm/memory.h" + #include "native/native.h" + #include "vm/builtin.h" -#include "vm/field.h" +#include "vm/exceptions.h" #include "vm/initialize.h" -#include "vm/options.h" -#include "vm/resolve.h" -#include "vm/references.h" + #include "vm/jit/asmpart.h" -#include "vm/jit/patcher.h" +#include "vm/jit/md.h" +#include "vm/jit/patcher-common.h" +#include "vmcore/class.h" +#include "vmcore/field.h" +#include "vmcore/options.h" +#include "vm/resolve.h" +#include "vmcore/references.h" -/* patcher_get_putstatic ******************************************************* - Machine code: +#define PATCH_BACK_ORIGINAL_MCODE \ + *((u4 *) pr->mpc) = (u4) pr->mcode; \ + md_icacheflush((u1 *) pr->mpc, PATCHER_CALL_SIZE); - - dfc1ffb8 ld at,-72(s8) - fc250000 sd a1,0(at) + +/* patcher_initialize_class **************************************************** + + Initalizes a given classinfo pointer. This function does not patch + any data. *******************************************************************************/ -bool patcher_get_putstatic(u1 *sp) +bool patcher_initialize_class(patchref_t *pr) { - u1 *ra; - java_objectheader *o; -#if SIZEOF_VOID_P == 8 - u8 mcode; -#else - u4 mcode[2]; -#endif - unresolved_field *uf; - s4 disp; - u1 *pv; - fieldinfo *fi; + classinfo *c; /* get stuff from the stack */ - ra = (u1 *) *((ptrint *) (sp + 5 * 8)); - o = (java_objectheader *) *((ptrint *) (sp + 4 * 8)); -#if SIZEOF_VOID_P == 8 - mcode = *((u8 *) (sp + 3 * 8)); -#else - mcode[0] = *((u4 *) (sp + 3 * 8)); - mcode[1] = *((u4 *) (sp + 3 * 8 + 4)); -#endif - uf = (unresolved_field *) *((ptrint *) (sp + 2 * 8)); - disp = *((s4 *) (sp + 1 * 8)); - pv = (u1 *) *((ptrint *) (sp + 0 * 8)); - - PATCHER_MONITORENTER; - - /* get the fieldinfo */ + c = (classinfo *) pr->ref; - if (!(fi = resolve_field_eager(uf))) { - PATCHER_MONITOREXIT; + /* check if the class is initialized */ - return false; - } + if (!(c->state & CLASS_INITIALIZED)) + if (!initialize_class(c)) + return false; - /* check if the field's class is initialized */ + PATCH_BACK_ORIGINAL_MCODE; - if (!fi->class->initialized) { - if (!initialize_class(fi->class)) { - PATCHER_MONITOREXIT; + return true; +} - return false; - } - } - /* patch back original code */ +/* patcher_resolve_class ***************************************************** -#if SIZEOF_VOID_P == 8 - *((u4 *) (ra + 0 * 4)) = mcode; - *((u4 *) (ra + 1 * 4)) = mcode >> 32; -#else - *((u4 *) (ra + 0 * 4)) = mcode[0]; - *((u4 *) (ra + 1 * 4)) = mcode[1]; -#endif + Initalizes a given classinfo pointer. This function does not patch + any data. - /* synchronize instruction cache */ +*******************************************************************************/ - cacheflush(ra, 2 * 4, ICACHE); +#ifdef ENABLE_VERIFIER +bool patcher_resolve_class(patchref_t *pr) +{ + unresolved_class *uc; - /* patch the field value's address */ + /* get stuff from the stack */ - *((ptrint *) (pv + disp)) = (ptrint) &(fi->value); + uc = (unresolved_class *) pr->ref; - /* synchronize data cache */ + /* resolve the class and check subtype constraints */ - cacheflush(pv + disp, SIZEOF_VOID_P, DCACHE); + if (!resolve_class_eager_no_access_check(uc)) + return false; - PATCHER_MARK_PATCHED_MONITOREXIT; + PATCH_BACK_ORIGINAL_MCODE; return true; } +#endif /* ENABLE_VERIFIER */ -/* patcher_get_putfield ******************************************************** +/* patcher_get_putstatic ******************************************************* Machine code: - 8ee90020 lw a5,32(s7) + dfc1ffb8 ld at,-72(s8) + fc250000 sd a1,0(at) *******************************************************************************/ -bool patcher_get_putfield(u1 *sp) +bool patcher_get_putstatic(patchref_t *pr) { - u1 *ra; - java_objectheader *o; -#if SIZEOF_VOID_P == 8 - u8 mcode; -#else - u4 mcode[2]; -#endif - unresolved_field *uf; - fieldinfo *fi; - - ra = (u1 *) *((ptrint *) (sp + 5 * 8)); - o = (java_objectheader *) *((ptrint *) (sp + 4 * 8)); -#if SIZEOF_VOID_P == 8 - mcode = *((u8 *) (sp + 3 * 8)); -#else - mcode[0] = *((u4 *) (sp + 3 * 8)); - mcode[1] = *((u4 *) (sp + 3 * 8 + 4)); -#endif - uf = (unresolved_field *) *((ptrint *) (sp + 2 * 8)); + unresolved_field *uf; + u1 *datap; + fieldinfo *fi; + + /* get stuff from the stack */ - PATCHER_MONITORENTER; + uf = (unresolved_field *) pr->ref; + datap = (u1 *) pr->datap; /* get the fieldinfo */ - if (!(fi = resolve_field_eager(uf))) { - PATCHER_MONITOREXIT; - + if (!(fi = resolve_field_eager(uf))) return false; - } - - /* patch back original code */ -#if SIZEOF_VOID_P == 8 - *((u4 *) (ra + 0 * 4)) = mcode; - *((u4 *) (ra + 1 * 4)) = mcode >> 32; -#else - *((u4 *) (ra + 0 * 4)) = mcode[0]; - *((u4 *) (ra + 1 * 4)) = mcode[1]; -#endif - - /* if we show disassembly, we have to skip the nop's */ + /* check if the field's class is initialized */ - if (opt_showdisassemble) - ra = ra + 2 * 4; + if (!(fi->class->state & CLASS_INITIALIZED)) + if (!initialize_class(fi->class)) + return false; - /* patch the field's offset */ + PATCH_BACK_ORIGINAL_MCODE; - *((u4 *) ra) |= (s2) (fi->offset & 0x0000ffff); + /* patch the field value's address */ - /* synchronize instruction cache */ + *((intptr_t *) datap) = (intptr_t) fi->value; - if (opt_showdisassemble) - cacheflush(ra - 2 * 4, 3 * 4, ICACHE); - else - cacheflush(ra, 2 * 4, ICACHE); + /* synchronize data cache */ - PATCHER_MARK_PATCHED_MONITOREXIT; + md_dcacheflush(datap, SIZEOF_VOID_P); return true; } -/* patcher_builtin_new ********************************************************* +/* patcher_get_putfield ******************************************************** Machine code: - dfc4ff98 ld a0,-104(s8) - - dfd9ff90 ld t9,-112(s8) - 0320f809 jalr t9 - 00000000 nop - - NOTICE: Only the displacement for the function address is passed, - but the address of the classinfo pointer is one below (above, in - addresses speaking). This is for sure. + + 8ee90020 lw a5,32(s7) *******************************************************************************/ -bool patcher_builtin_new(u1 *sp) +bool patcher_get_putfield(patchref_t *pr) { - u1 *ra; - java_objectheader *o; -#if SIZEOF_VOID_P == 8 - u8 mcode; -#else - u4 mcode[2]; -#endif - constant_classref *cr; - s4 disp; - u1 *pv; - classinfo *c; + u1 *ra; + unresolved_field *uf; + fieldinfo *fi; /* get stuff from the stack */ - ra = (u1 *) *((ptrint *) (sp + 5 * 8)); - o = (java_objectheader *) *((ptrint *) (sp + 4 * 8)); -#if SIZEOF_VOID_P == 8 - mcode = *((u8 *) (sp + 3 * 8)); -#else - mcode[0] = *((u4 *) (sp + 3 * 8)); - mcode[1] = *((u4 *) (sp + 3 * 8 + 4)); -#endif - cr = (constant_classref *) *((ptrint *) (sp + 2 * 8)); - disp = *((s4 *) (sp + 1 * 8)); - pv = (u1 *) *((ptrint *) (sp + 0 * 8)); - - /* calculate and set the new return address */ + ra = (u1 *) pr->mpc; + uf = (unresolved_field *) pr->ref; - ra = ra - 1 * 4; - *((ptrint *) (sp + 5 * 8)) = (ptrint) ra; + /* get the fieldinfo */ - PATCHER_MONITORENTER; + if (!(fi = resolve_field_eager(uf))) + return false; - /* get the classinfo */ + PATCH_BACK_ORIGINAL_MCODE; - if (!(c = resolve_classref_eager_nonabstract(cr))) { - PATCHER_MONITOREXIT; + /* if we show disassembly, we have to skip the nop's */ - return false; + if (opt_shownops) + ra = ra + PATCHER_CALL_SIZE; + +#if SIZEOF_VOID_P == 4 + if (IS_LNG_TYPE(fi->type)) { +# if WORDS_BIGENDIAN == 1 + /* ATTENTION: order of these instructions depend on M_LLD_INTERN */ + *((u4 *) (ra + 0 * 4)) |= (s2) ((fi->offset + 0) & 0x0000ffff); + *((u4 *) (ra + 1 * 4)) |= (s2) ((fi->offset + 4) & 0x0000ffff); +# else + /* ATTENTION: order of these instructions depend on M_LLD_INTERN */ + *((u4 *) (ra + 0 * 4)) |= (s2) ((fi->offset + 4) & 0x0000ffff); + *((u4 *) (ra + 1 * 4)) |= (s2) ((fi->offset + 0) & 0x0000ffff); +# endif } - - /* patch back original code */ - -#if SIZEOF_VOID_P == 8 - *((u4 *) (ra + 1 * 4)) = mcode; - *((u4 *) (ra + 2 * 4)) = mcode >> 32; -#else - *((u4 *) (ra + 1 * 4)) = mcode[0]; - *((u4 *) (ra + 2 * 4)) = mcode[1]; + else #endif + *((u4 *) (ra + 0 * 4)) |= (s2) (fi->offset & 0x0000ffff); /* synchronize instruction cache */ - cacheflush(ra + 1 * 4, 2 * 4, ICACHE); + md_icacheflush(ra, 2 * 4); - /* patch the classinfo pointer */ - - *((ptrint *) (pv + (disp + SIZEOF_VOID_P))) = (ptrint) c; + return true; +} - /* patch new function address */ - *((ptrint *) (pv + disp)) = (ptrint) BUILTIN_new; +/* patcher_resolve_classref_to_classinfo *************************************** - PATCHER_MARK_PATCHED_MONITOREXIT; + ACONST: - return true; -} + + dfc4ff98 ld a0,-104(s8) + MULTIANEWARRAY: -/* patcher_builtin_newarray **************************************************** + + dfc5ff90 ld a1,-112(s8) + 03a03025 move a2,sp + dfd9ff88 ld t9,-120(s8) + 0320f809 jalr t9 + 00000000 nop - Machine code: + ARRAYCHECKCAST: - dfc5ffa0 ld a1,-96(s8) - dfd9ff98 ld t9,-104(s8) + dfc5ffc0 ld a1,-64(s8) + dfd9ffb8 ld t9,-72(s8) 0320f809 jalr t9 00000000 nop - NOTICE: Only the displacement for the function address is passed, - but the address of the classinfo pointer is one below (above, in - addresses speaking). This is for sure. - *******************************************************************************/ -bool patcher_builtin_newarray(u1 *sp) +bool patcher_resolve_classref_to_classinfo(patchref_t *pr) { - u1 *ra; - java_objectheader *o; -#if SIZEOF_VOID_P == 8 - u8 mcode; -#else - u4 mcode[2]; -#endif constant_classref *cr; - s4 disp; - u1 *pv; + u1 *datap; classinfo *c; /* get stuff from the stack */ - ra = (u1 *) *((ptrint *) (sp + 5 * 8)); - o = (java_objectheader *) *((ptrint *) (sp + 4 * 8)); -#if SIZEOF_VOID_P == 8 - mcode = *((u8 *) (sp + 3 * 8)); -#else - mcode[0] = *((u4 *) (sp + 3 * 8)); - mcode[1] = *((u4 *) (sp + 3 * 8 + 4)); -#endif - cr = (constant_classref *) *((ptrint *) (sp + 2 * 8)); - 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; - - PATCHER_MONITORENTER; + cr = (constant_classref *) pr->ref; + datap = (u1 *) pr->datap; /* get the classinfo */ - if (!(c = resolve_classref_eager(cr))) { - PATCHER_MONITOREXIT; - + if (!(c = resolve_classref_eager(cr))) return false; - } - - /* patch back original code */ - -#if SIZEOF_VOID_P == 8 - *((u4 *) (ra + 1 * 4)) = mcode; - *((u4 *) (ra + 2 * 4)) = mcode >> 32; -#else - *((u4 *) (ra + 1 * 4)) = mcode[0]; - *((u4 *) (ra + 2 * 4)) = mcode[1]; -#endif - - /* synchronize instruction cache */ - cacheflush(ra + 1 * 4, 2 * 4, ICACHE); + PATCH_BACK_ORIGINAL_MCODE; - /* patch the class' vftbl pointer */ - - *((ptrint *) (pv + (disp + SIZEOF_VOID_P))) = (ptrint) c->vftbl; + /* patch the classinfo pointer */ - /* patch new function address */ + *((intptr_t *) datap) = (intptr_t) c; - *((ptrint *) (pv + disp)) = (ptrint) BUILTIN_newarray; + /* synchronize data cache */ - PATCHER_MARK_PATCHED_MONITOREXIT; + md_dcacheflush(datap, SIZEOF_VOID_P); return true; } -/* patcher_builtin_multianewarray ********************************************** +/* patcher_resolve_classref_to_vftbl ******************************************* - Machine code: + CHECKCAST (class): + INSTANCEOF (class): - dfc5ff90 ld a1,-112(s8) - 03a03025 move a2,sp - dfd9ff88 ld t9,-120(s8) - 0320f809 jalr t9 - 00000000 nop + dd030000 ld v1,0(a4) + dfd9ff18 ld t9,-232(s8) *******************************************************************************/ -bool patcher_builtin_multianewarray(u1 *sp) +bool patcher_resolve_classref_to_vftbl(patchref_t *pr) { - u1 *ra; - java_objectheader *o; -#if SIZEOF_VOID_P == 8 - u8 mcode; -#else - u4 mcode[2]; -#endif constant_classref *cr; - s4 disp; - u1 *pv; + u1 *datap; classinfo *c; /* get stuff from the stack */ - ra = (u1 *) *((ptrint *) (sp + 5 * 8)); - o = (java_objectheader *) *((ptrint *) (sp + 4 * 8)); -#if SIZEOF_VOID_P == 8 - mcode = *((u8 *) (sp + 3 * 8)); -#else - mcode[0] = *((u4 *) (sp + 3 * 8)); - mcode[1] = *((u4 *) (sp + 3 * 8 + 4)); -#endif - cr = (constant_classref *) *((ptrint *) (sp + 2 * 8)); - disp = *((s4 *) (sp + 1 * 8)); - pv = (u1 *) *((ptrint *) (sp + 0 * 8)); - - PATCHER_MONITORENTER; - - /* get the classinfo */ + cr = (constant_classref *) pr->ref; + datap = (u1 *) pr->datap; - if (!(c = resolve_classref_eager(cr))) { - PATCHER_MONITOREXIT; + /* get the fieldinfo */ + if (!(c = resolve_classref_eager(cr))) return false; - } - /* patch back original code */ + PATCH_BACK_ORIGINAL_MCODE; -#if SIZEOF_VOID_P == 8 - *((u4 *) (ra + 0 * 4)) = mcode; - *((u4 *) (ra + 1 * 4)) = mcode >> 32; -#else - *((u4 *) (ra + 0 * 4)) = mcode[0]; - *((u4 *) (ra + 1 * 4)) = mcode[1]; -#endif - - /* synchronize instruction cache */ - - cacheflush(ra, 2 * 4, ICACHE); + /* patch super class' vftbl */ - /* patch the class' vftbl pointer */ + *((intptr_t *) datap) = (intptr_t) c->vftbl; - *((ptrint *) (pv + disp)) = (ptrint) c->vftbl; + /* synchronize data cache */ - PATCHER_MARK_PATCHED_MONITOREXIT; + md_dcacheflush(datap, SIZEOF_VOID_P); return true; } -/* patcher_builtin_arraycheckcast ********************************************** +/* patcher_resolve_classref_to_flags ******************************************* - Machine code: + CHECKCAST/INSTANCEOF: - dfc5ffc0 ld a1,-64(s8) - dfd9ffb8 ld t9,-72(s8) - 0320f809 jalr t9 + 8fc3ff24 lw v1,-220(s8) + 30630200 andi v1,v1,512 + 1060000d beq v1,zero,0x000000001051824c 00000000 nop - NOTICE: Only the displacement of the vftbl pointer address is - passed, but the address of the function pointer is one above - (below, in addresses speaking). This is for sure. - *******************************************************************************/ -bool patcher_builtin_arraycheckcast(u1 *sp) +bool patcher_resolve_classref_to_flags(patchref_t *pr) { - u1 *ra; - java_objectheader *o; -#if SIZEOF_VOID_P == 8 - u8 mcode; -#else - u4 mcode[2]; -#endif constant_classref *cr; - s4 disp; - u1 *pv; + u1 *datap; classinfo *c; /* get stuff from the stack */ - ra = (u1 *) *((ptrint *) (sp + 5 * 8)); - o = (java_objectheader *) *((ptrint *) (sp + 4 * 8)); -#if SIZEOF_VOID_P == 8 - mcode = *((u8 *) (sp + 3 * 8)); -#else - mcode[0] = *((u4 *) (sp + 3 * 8)); - mcode[1] = *((u4 *) (sp + 3 * 8 + 4)); -#endif - cr = (constant_classref *) *((ptrint *) (sp + 2 * 8)); - disp = *((s4 *) (sp + 1 * 8)); - pv = (u1 *) *((ptrint *) (sp + 0 * 8)); - - PATCHER_MONITORENTER; + cr = (constant_classref *) pr->ref; + datap = (u1 *) pr->datap; - /* get the classinfo */ - - if (!(c = resolve_classref_eager(cr))) { - PATCHER_MONITOREXIT; + /* get the fieldinfo */ + if (!(c = resolve_classref_eager(cr))) return false; - } - /* patch back original code */ + PATCH_BACK_ORIGINAL_MCODE; -#if SIZEOF_VOID_P == 8 - *((u4 *) (ra + 0 * 4)) = mcode; - *((u4 *) (ra + 1 * 4)) = mcode >> 32; -#else - *((u4 *) (ra + 0 * 4)) = mcode[0]; - *((u4 *) (ra + 1 * 4)) = mcode[1]; -#endif - - /* synchronize instruction cache */ - - cacheflush(ra, 2 * 4, ICACHE); - - /* patch the class' vftbl pointer */ - - *((ptrint *) (pv + disp)) = (ptrint) c->vftbl; + /* patch class flags */ - /* patch new function address */ + *((int32_t *) datap) = (int32_t) c->flags; - *((ptrint *) (pv + (disp - SIZEOF_VOID_P))) = - (ptrint) BUILTIN_arraycheckcast; + /* synchronize data cache */ - PATCHER_MARK_PATCHED_MONITOREXIT; + md_dcacheflush(datap, sizeof(int32_t)); return true; } -/* patcher_builtin_arrayinstanceof ********************************************* - - Machine code: - - dfc5fe98 ld a1,-360(s8) - - dfd9fe90 ld t9,-368(s8) - 0320f809 jalr t9 - 00000000 nop +/* patcher_resolve_native ****************************************************** - NOTICE: Only the displacement for the function address is passed, - but the address of the vftbl pointer is one below (above, in - addresses speaking). This is for sure. + XXX *******************************************************************************/ -bool patcher_builtin_arrayinstanceof(u1 *sp) +#if !defined(WITH_STATIC_CLASSPATH) +bool patcher_resolve_native_function(patchref_t *pr) { - u1 *ra; - java_objectheader *o; -#if SIZEOF_VOID_P == 8 - u8 mcode; -#else - u4 mcode[2]; -#endif - constant_classref *cr; - s4 disp; - u1 *pv; - classinfo *c; + methodinfo *m; + u1 *datap; + functionptr f; /* get stuff from the stack */ - ra = (u1 *) *((ptrint *) (sp + 5 * 8)); - o = (java_objectheader *) *((ptrint *) (sp + 4 * 8)); -#if SIZEOF_VOID_P == 8 - mcode = *((u8 *) (sp + 3 * 8)); -#else - mcode[0] = *((u4 *) (sp + 3 * 8)); - mcode[1] = *((u4 *) (sp + 3 * 8 + 4)); -#endif - cr = (constant_classref *) *((ptrint *) (sp + 2 * 8)); - 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; - - PATCHER_MONITORENTER; + m = (methodinfo *) pr->ref; + datap = (u1 *) pr->datap; - /* get the classinfo */ - - if (!(c = resolve_classref_eager(cr))) { - PATCHER_MONITOREXIT; + /* resolve native function */ + if (!(f = native_resolve_function(m))) return false; - } - - /* patch back original code */ - -#if SIZEOF_VOID_P == 8 - *((u4 *) (ra + 1 * 4)) = mcode; - *((u4 *) (ra + 2 * 4)) = mcode >> 32; -#else - *((u4 *) (ra + 1 * 4)) = mcode[0]; - *((u4 *) (ra + 2 * 4)) = mcode[1]; -#endif - - /* synchronize instruction cache */ - cacheflush(ra + 1 * 4, 2 * 4, ICACHE); + PATCH_BACK_ORIGINAL_MCODE; - /* patch the class' vftbl pointer */ - - *((ptrint *) (pv + (disp + SIZEOF_VOID_P))) = (ptrint) c->vftbl; + /* patch native function pointer */ - /* patch new function address */ + *((ptrint *) datap) = (ptrint) f; - *((ptrint *) (pv + disp)) = (ptrint) BUILTIN_arrayinstanceof; + /* synchronize data cache */ - PATCHER_MARK_PATCHED_MONITOREXIT; + md_dcacheflush(datap, SIZEOF_VOID_P); return true; } +#endif /* !defined(WITH_STATIC_CLASSPATH) */ /* patcher_invokestatic_special ************************************************ @@ -639,63 +403,31 @@ bool patcher_builtin_arrayinstanceof(u1 *sp) ******************************************************************************/ -bool patcher_invokestatic_special(u1 *sp) +bool patcher_invokestatic_special(patchref_t *pr) { - u1 *ra; - java_objectheader *o; -#if SIZEOF_VOID_P == 8 - u8 mcode; -#else - u4 mcode[2]; -#endif unresolved_method *um; - s4 disp; - u1 *pv; + u1 *datap; methodinfo *m; /* get stuff from the stack */ - ra = (u1 *) *((ptrint *) (sp + 5 * 8)); - o = (java_objectheader *) *((ptrint *) (sp + 4 * 8)); -#if SIZEOF_VOID_P == 8 - mcode = *((u8 *) (sp + 3 * 8)); -#else - mcode[0] = *((u4 *) (sp + 3 * 8)); - mcode[1] = *((u4 *) (sp + 3 * 8 + 4)); -#endif - um = (unresolved_method *) *((ptrint *) (sp + 2 * 8)); - disp = *((s4 *) (sp + 1 * 8)); - pv = (u1 *) *((ptrint *) (sp + 0 * 8)); - - PATCHER_MONITORENTER; + um = (unresolved_method *) pr->ref; + datap = (u1 *) pr->datap; /* get the fieldinfo */ - if (!(m = resolve_method_eager(um))) { - PATCHER_MONITOREXIT; - + if (!(m = resolve_method_eager(um))) return false; - } - - /* patch back original code */ - -#if SIZEOF_VOID_P == 8 - *((u4 *) (ra + 0 * 4)) = mcode; - *((u4 *) (ra + 1 * 4)) = mcode >> 32; -#else - *((u4 *) (ra + 0 * 4)) = mcode[0]; - *((u4 *) (ra + 1 * 4)) = mcode[1]; -#endif - - /* synchronize instruction cache */ - cacheflush(ra, 2 * 4, ICACHE); + PATCH_BACK_ORIGINAL_MCODE; /* patch stubroutine */ - *((ptrint *) (pv + disp)) = (ptrint) m->stubroutine; + *((ptrint *) datap) = (ptrint) m->stubroutine; - PATCHER_MARK_PATCHED_MONITOREXIT; + /* synchronize data cache */ + + md_dcacheflush(datap, SIZEOF_VOID_P); return true; } @@ -713,68 +445,38 @@ bool patcher_invokestatic_special(u1 *sp) *******************************************************************************/ -bool patcher_invokevirtual(u1 *sp) +bool patcher_invokevirtual(patchref_t *pr) { u1 *ra; - java_objectheader *o; -#if SIZEOF_VOID_P == 8 - u8 mcode; -#else - u4 mcode[2]; -#endif unresolved_method *um; methodinfo *m; /* get stuff from the stack */ - ra = (u1 *) *((ptrint *) (sp + 5 * 8)); - o = (java_objectheader *) *((ptrint *) (sp + 4 * 8)); -#if SIZEOF_VOID_P == 8 - mcode = *((u8 *) (sp + 3 * 8)); -#else - mcode[0] = *((u4 *) (sp + 3 * 8)); - mcode[1] = *((u4 *) (sp + 3 * 8 + 4)); -#endif - um = (unresolved_method *) *((ptrint *) (sp + 2 * 8)); - - PATCHER_MONITORENTER; + ra = (u1 *) pr->mpc; + um = (unresolved_method *) pr->ref; /* get the fieldinfo */ - if (!(m = resolve_method_eager(um))) { - PATCHER_MONITOREXIT; - + if (!(m = resolve_method_eager(um))) return false; - } - - /* patch back original code */ -#if SIZEOF_VOID_P == 8 - *((u4 *) (ra + 0 * 4)) = mcode; - *((u4 *) (ra + 1 * 4)) = mcode >> 32; -#else - *((u4 *) (ra + 0 * 4)) = mcode[0]; - *((u4 *) (ra + 1 * 4)) = mcode[1]; -#endif + PATCH_BACK_ORIGINAL_MCODE; /* if we show disassembly, we have to skip the nop's */ - if (opt_showdisassemble) - ra = ra + 2 * 4; + if (opt_shownops) + ra = ra + PATCHER_CALL_SIZE; /* patch vftbl index */ - *((s4 *) (ra + 1 * 4)) |= (s4) ((OFFSET(vftbl_t, table[0]) + - sizeof(methodptr) * m->vftblindex) & 0x0000ffff); + *((s4 *) (ra + 1 * 4)) |= + (s4) ((OFFSET(vftbl_t, table[0]) + + sizeof(methodptr) * m->vftblindex) & 0x0000ffff); /* synchronize instruction cache */ - if (opt_showdisassemble) - cacheflush(ra - 2 * 4, 4 * 4, ICACHE); - else - cacheflush(ra, 2 * 4, ICACHE); - - PATCHER_MARK_PATCHED_MONITOREXIT; + md_icacheflush(ra + 1 * 4, 1 * 4); return true; } @@ -793,59 +495,34 @@ bool patcher_invokevirtual(u1 *sp) *******************************************************************************/ -bool patcher_invokeinterface(u1 *sp) +bool patcher_invokeinterface(patchref_t *pr) { u1 *ra; - java_objectheader *o; -#if SIZEOF_VOID_P == 8 - u8 mcode; -#else - u4 mcode[2]; -#endif unresolved_method *um; methodinfo *m; /* get stuff from the stack */ - ra = (u1 *) *((ptrint *) (sp + 5 * 8)); - o = (java_objectheader *) *((ptrint *) (sp + 4 * 8)); -#if SIZEOF_VOID_P == 8 - mcode = *((u8 *) (sp + 3 * 8)); -#else - mcode[0] = *((u4 *) (sp + 3 * 8)); - mcode[1] = *((u4 *) (sp + 3 * 8 + 4)); -#endif - um = (unresolved_method *) *((ptrint *) (sp + 2 * 8)); - - PATCHER_MONITORENTER; + ra = (u1 *) pr->mpc; + um = (unresolved_method *) pr->ref; /* get the fieldinfo */ - if (!(m = resolve_method_eager(um))) { - PATCHER_MONITOREXIT; - + if (!(m = resolve_method_eager(um))) return false; - } - - /* patch back original code */ -#if SIZEOF_VOID_P == 8 - *((u4 *) (ra + 0 * 4)) = mcode; - *((u4 *) (ra + 1 * 4)) = mcode >> 32; -#else - *((u4 *) (ra + 0 * 4)) = mcode[0]; - *((u4 *) (ra + 1 * 4)) = mcode[1]; -#endif + PATCH_BACK_ORIGINAL_MCODE; /* if we show disassembly, we have to skip the nop's */ - if (opt_showdisassemble) - ra = ra + 2 * 4; + if (opt_shownops) + ra = ra + PATCHER_CALL_SIZE; /* patch interfacetable index */ - *((s4 *) (ra + 1 * 4)) |= (s4) ((OFFSET(vftbl_t, interfacetable[0]) - - sizeof(methodptr*) * m->class->index) & 0x0000ffff); + *((s4 *) (ra + 1 * 4)) |= + (s4) ((OFFSET(vftbl_t, interfacetable[0]) - + sizeof(methodptr*) * m->class->index) & 0x0000ffff); /* patch method offset */ @@ -854,92 +531,13 @@ bool patcher_invokeinterface(u1 *sp) /* synchronize instruction cache */ - if (opt_showdisassemble) - cacheflush(ra - 2 * 4, 5 * 4, ICACHE); - else - cacheflush(ra, 3 * 4, ICACHE); - - PATCHER_MARK_PATCHED_MONITOREXIT; + md_icacheflush(ra + 1 * 4, 2 * 4); return true; } -/* patcher_checkcast_instanceof_flags ****************************************** - - Machine code: - - - 8fc3ff24 lw v1,-220(s8) - 30630200 andi v1,v1,512 - 1060000d beq v1,zero,0x000000001051824c - 00000000 nop - -*******************************************************************************/ - -bool patcher_checkcast_instanceof_flags(u1 *sp) -{ - u1 *ra; - java_objectheader *o; -#if SIZEOF_VOID_P == 8 - u8 mcode; -#else - u4 mcode[2]; -#endif - constant_classref *cr; - s4 disp; - u1 *pv; - classinfo *c; - - /* get stuff from the stack */ - - ra = (u1 *) *((ptrint *) (sp + 5 * 8)); - o = (java_objectheader *) *((ptrint *) (sp + 4 * 8)); -#if SIZEOF_VOID_P == 8 - mcode = *((u8 *) (sp + 3 * 8)); -#else - mcode[0] = *((u4 *) (sp + 3 * 8)); - mcode[1] = *((u4 *) (sp + 3 * 8 + 4)); -#endif - cr = (constant_classref *) *((ptrint *) (sp + 2 * 8)); - disp = *((s4 *) (sp + 1 * 8)); - pv = (u1 *) *((ptrint *) (sp + 0 * 8)); - - PATCHER_MONITORENTER; - - /* get the fieldinfo */ - - if (!(c = resolve_classref_eager(cr))) { - PATCHER_MONITOREXIT; - - return false; - } - - /* patch back original code */ - -#if SIZEOF_VOID_P == 8 - *((u4 *) (ra + 0 * 4)) = mcode; - *((u4 *) (ra + 1 * 4)) = mcode >> 32; -#else - *((u4 *) (ra + 0 * 4)) = mcode[0]; - *((u4 *) (ra + 1 * 4)) = mcode[1]; -#endif - - /* synchronize instruction cache */ - - cacheflush(ra, 2 * 4, ICACHE); - - /* patch class flags */ - - *((s4 *) (pv + disp)) = (s4) c->flags; - - PATCHER_MARK_PATCHED_MONITOREXIT; - - return true; -} - - -/* patcher_checkcast_instanceof_interface ************************************** +/* patcher_checkcast_interface ************************************************* Machine code: @@ -953,343 +551,96 @@ bool patcher_checkcast_instanceof_flags(u1 *sp) *******************************************************************************/ -bool patcher_checkcast_instanceof_interface(u1 *sp) +bool patcher_checkcast_interface(patchref_t *pr) { u1 *ra; - java_objectheader *o; -#if SIZEOF_VOID_P == 8 - u8 mcode; -#else - u4 mcode[2]; -#endif constant_classref *cr; classinfo *c; /* get stuff from the stack */ - ra = (u1 *) *((ptrint *) (sp + 5 * 8)); - o = (java_objectheader *) *((ptrint *) (sp + 4 * 8)); -#if SIZEOF_VOID_P == 8 - mcode = *((u8 *) (sp + 3 * 8)); -#else - mcode[0] = *((u4 *) (sp + 3 * 8)); - mcode[1] = *((u4 *) (sp + 3 * 8 + 4)); -#endif - cr = (constant_classref *) *((ptrint *) (sp + 2 * 8)); - - PATCHER_MONITORENTER; + ra = (u1 *) pr->mpc; + cr = (constant_classref *) pr->ref; /* get the fieldinfo */ - if (!(c = resolve_classref_eager(cr))) { - PATCHER_MONITOREXIT; - + if (!(c = resolve_classref_eager(cr))) return false; - } - /* patch back original code */ - -#if SIZEOF_VOID_P == 8 - *((u4 *) (ra + 0 * 4)) = mcode; - *((u4 *) (ra + 1 * 4)) = mcode >> 32; -#else - *((u4 *) (ra + 0 * 4)) = mcode[0]; - *((u4 *) (ra + 1 * 4)) = mcode[1]; -#endif + PATCH_BACK_ORIGINAL_MCODE; /* if we show disassembly, we have to skip the nop's */ - if (opt_showdisassemble) - ra = ra + 2 * 4; + if (opt_shownops) + ra = ra + PATCHER_CALL_SIZE; /* patch super class index */ *((s4 *) (ra + 2 * 4)) |= (s4) (-(c->index) & 0x0000ffff); - - *((s4 *) (ra + 5 * 4)) |= (s4) ((OFFSET(vftbl_t, interfacetable[0]) - - c->index * sizeof(methodptr*)) & 0x0000ffff); + /* *((s4 *) (ra + 5 * 4)) |= (s4) ((OFFSET(vftbl_t, interfacetable[0]) - */ + /* c->index * sizeof(methodptr*)) & 0x0000ffff); */ + *((s4 *) (ra + 6 * 4)) |= + (s4) ((OFFSET(vftbl_t, interfacetable[0]) - + c->index * sizeof(methodptr*)) & 0x0000ffff); /* synchronize instruction cache */ - if (opt_showdisassemble) - cacheflush(ra - 2 * 4, 8 * 4, ICACHE); - else - cacheflush(ra, 6 * 4, ICACHE); - - PATCHER_MARK_PATCHED_MONITOREXIT; + md_icacheflush(ra + 2 * 4, 5 * 4); return true; } -/* patcher_checkcast_instanceof_class ****************************************** +/* patcher_instanceof_interface ************************************************ Machine code: dd030000 ld v1,0(a4) - dfd9ff18 ld t9,-232(s8) + 8c79001c lw t9,28(v1) + 27390000 addiu t9,t9,0 + 1b200082 blez t9,zero,0x000000001051843c + 00000000 nop + dc790000 ld t9,0(v1) *******************************************************************************/ -bool patcher_checkcast_instanceof_class(u1 *sp) +bool patcher_instanceof_interface(patchref_t *pr) { u1 *ra; - java_objectheader *o; -#if SIZEOF_VOID_P == 8 - u8 mcode; -#else - u4 mcode[2]; -#endif constant_classref *cr; - s4 disp; - u1 *pv; classinfo *c; /* get stuff from the stack */ - ra = (u1 *) *((ptrint *) (sp + 5 * 8)); - o = (java_objectheader *) *((ptrint *) (sp + 4 * 8)); -#if SIZEOF_VOID_P == 8 - mcode = *((u8 *) (sp + 3 * 8)); -#else - mcode[0] = *((u4 *) (sp + 3 * 8)); - mcode[1] = *((u4 *) (sp + 3 * 8 + 4)); -#endif - cr = (constant_classref *) *((ptrint *) (sp + 2 * 8)); - disp = *((s4 *) (sp + 1 * 8)); - pv = (u1 *) *((ptrint *) (sp + 0 * 8)); - - PATCHER_MONITORENTER; + ra = (u1 *) pr->mpc; + cr = (constant_classref *) pr->ref; /* get the fieldinfo */ - if (!(c = resolve_classref_eager(cr))) { - PATCHER_MONITOREXIT; - + if (!(c = resolve_classref_eager(cr))) return false; - } - - /* patch back original code */ - -#if SIZEOF_VOID_P == 8 - *((u4 *) (ra + 0 * 4)) = mcode; - *((u4 *) (ra + 1 * 4)) = mcode >> 32; -#else - *((u4 *) (ra + 0 * 4)) = mcode[0]; - *((u4 *) (ra + 1 * 4)) = mcode[1]; -#endif - - /* synchronize instruction cache */ - - cacheflush(ra, 2 * 4, ICACHE); - - /* patch super class' vftbl */ - - *((ptrint *) (pv + disp)) = (ptrint) c->vftbl; - PATCHER_MARK_PATCHED_MONITOREXIT; + PATCH_BACK_ORIGINAL_MCODE; - return true; -} - - -/* patcher_clinit ************************************************************** - - No special machine code. - -*******************************************************************************/ - -bool patcher_clinit(u1 *sp) -{ - u1 *ra; - java_objectheader *o; -#if SIZEOF_VOID_P == 8 - u8 mcode; -#else - u4 mcode[2]; -#endif - classinfo *c; - - /* get stuff from the stack */ - - ra = (u1 *) *((ptrint *) (sp + 5 * 8)); - o = (java_objectheader *) *((ptrint *) (sp + 4 * 8)); -#if SIZEOF_VOID_P == 8 - mcode = *((u8 *) (sp + 3 * 8)); -#else - mcode[0] = *((u4 *) (sp + 3 * 8)); - mcode[1] = *((u4 *) (sp + 3 * 8 + 4)); -#endif - c = (classinfo *) *((ptrint *) (sp + 2 * 8)); - - PATCHER_MONITORENTER; - - /* check if the class is initialized */ - - if (!c->initialized) { - if (!initialize_class(c)) { - PATCHER_MONITOREXIT; - - return false; - } - } - - /* patch back original code */ - -#if SIZEOF_VOID_P == 8 - *((u4 *) (ra + 0 * 4)) = mcode; - *((u4 *) (ra + 1 * 4)) = mcode >> 32; -#else - *((u4 *) (ra + 0 * 4)) = mcode[0]; - *((u4 *) (ra + 1 * 4)) = mcode[1]; -#endif - - /* synchronize instruction cache */ - - cacheflush(ra, 2 * 4, ICACHE); - - PATCHER_MARK_PATCHED_MONITOREXIT; - - return true; -} - - -/* patcher_athrow_areturn ****************************************************** - - Machine code: - - - -*******************************************************************************/ - -bool patcher_athrow_areturn(u1 *sp) -{ - u1 *ra; - java_objectheader *o; -#if SIZEOF_VOID_P == 8 - u8 mcode; -#else - u4 mcode[2]; -#endif - unresolved_class *uc; - classinfo *c; - - /* get stuff from the stack */ - - ra = (u1 *) *((ptrint *) (sp + 5 * 8)); - o = (java_objectheader *) *((ptrint *) (sp + 4 * 8)); -#if SIZEOF_VOID_P == 8 - mcode = *((u8 *) (sp + 3 * 8)); -#else - mcode[0] = *((u4 *) (sp + 3 * 8)); - mcode[1] = *((u4 *) (sp + 3 * 8 + 4)); -#endif - uc = (unresolved_class *) *((ptrint *) (sp + 2 * 8)); - - PATCHER_MONITORENTER; - - /* resolve the class */ - - if (!resolve_class(uc, resolveEager, false, &c)) { - PATCHER_MONITOREXIT; - - return false; - } - - /* patch back original code */ - -#if SIZEOF_VOID_P == 8 - *((u4 *) (ra + 0 * 4)) = mcode; - *((u4 *) (ra + 1 * 4)) = mcode >> 32; -#else - *((u4 *) (ra + 0 * 4)) = mcode[0]; - *((u4 *) (ra + 1 * 4)) = mcode[1]; -#endif - - /* synchronize instruction cache */ - - cacheflush(ra, 2 * 4, ICACHE); - - PATCHER_MARK_PATCHED_MONITOREXIT; - - return true; -} - - -/* patcher_resolve_native ****************************************************** - - XXX - -*******************************************************************************/ - -#if !defined(ENABLE_STATICVM) -bool patcher_resolve_native(u1 *sp) -{ - u1 *ra; - java_objectheader *o; -#if SIZEOF_VOID_P == 8 - u8 mcode; -#else - u4 mcode[2]; -#endif - methodinfo *m; - s4 disp; - u1 *pv; - functionptr f; - - /* get stuff from the stack */ - - ra = (u1 *) *((ptrint *) (sp + 5 * 8)); - o = (java_objectheader *) *((ptrint *) (sp + 4 * 8)); -#if SIZEOF_VOID_P == 8 - mcode = *((u8 *) (sp + 3 * 8)); -#else - mcode[0] = *((u4 *) (sp + 3 * 8)); - mcode[1] = *((u4 *) (sp + 3 * 8 + 4)); -#endif - m = (methodinfo *) *((ptrint *) (sp + 2 * 8)); - disp = *((s4 *) (sp + 1 * 8)); - pv = (u1 *) *((ptrint *) (sp + 0 * 8)); - - /* calculate and set the new return address */ - - ra = ra - 2 * 4; - *((ptrint *) (sp + 5 * 8)) = (ptrint) ra; - - PATCHER_MONITORENTER; - - /* resolve native function */ - - if (!(f = native_resolve_function(m))) { - PATCHER_MONITOREXIT; + /* if we show disassembly, we have to skip the nop's */ - return false; - } + if (opt_shownops) + ra = ra + PATCHER_CALL_SIZE; - /* patch back original code */ + /* patch super class index */ -#if SIZEOF_VOID_P == 8 - *((u4 *) (ra + 0 * 4)) = mcode; - *((u4 *) (ra + 1 * 4)) = mcode >> 32; -#else - *((u4 *) (ra + 0 * 4)) = mcode[0]; - *((u4 *) (ra + 1 * 4)) = mcode[1]; -#endif + *((s4 *) (ra + 2 * 4)) |= (s4) (-(c->index) & 0x0000ffff); + *((s4 *) (ra + 5 * 4)) |= + (s4) ((OFFSET(vftbl_t, interfacetable[0]) - + c->index * sizeof(methodptr*)) & 0x0000ffff); /* synchronize instruction cache */ - cacheflush(ra, 2 * 4, ICACHE); - - /* patch native function pointer */ - - *((ptrint *) (pv + disp)) = (ptrint) f; - - PATCHER_MARK_PATCHED_MONITOREXIT; + md_icacheflush(ra + 2 * 4, 4 * 4); return true; } -#endif /* !defined(ENABLE_STATICVM) */ /*