X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=src%2Fvm%2Fjit%2Fpowerpc%2Fpatcher.c;h=d941b7d632e95e76426f7c100b245c56d534c7f3;hb=9f859ad50d3d5d98c185d40b86b2179bc4dc9aeb;hp=9bee19be82500871369d11e1e6bf7d6e92e95259;hpb=add838b8b89de688d4e25f5653a0957a6dbf8c02;p=cacao.git diff --git a/src/vm/jit/powerpc/patcher.c b/src/vm/jit/powerpc/patcher.c index 9bee19be8..d941b7d63 100644 --- a/src/vm/jit/powerpc/patcher.c +++ b/src/vm/jit/powerpc/patcher.c @@ -1,9 +1,9 @@ /* src/vm/jit/powerpc/patcher.c - PowerPC 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,567 +19,391 @@ 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. + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301, USA. - Contact: cacao@complang.tuwien.ac.at +*/ - Authors: Christian Thalinger - Changes: +#include "config.h" - $Id: patcher.c 2537 2005-05-31 15:54:27Z twisti $ +#include +#include -*/ +#include "vm/types.h" +#include "mm/memory.h" +#include "native/native.h" -#include "vm/jit/powerpc/types.h" #include "vm/builtin.h" -#include "vm/field.h" +#include "vm/exceptions.h" #include "vm/initialize.h" -#include "vm/options.h" -#include "vm/references.h" + #include "vm/jit/asmpart.h" -#include "vm/jit/helper.h" -#include "vm/jit/patcher.h" +#include "vm/jit/md.h" +#include "vm/jit/methodheader.h" +#include "vm/jit/patcher-common.h" +#include "vm/jit/stacktrace.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, 4); - - 816dffc8 lwz r11,-56(r13) - 80ab0000 lwz r5,0(r11) + +/* 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; - u4 mcode; - unresolved_field *uf; - u1 *pv; - fieldinfo *fi; - s2 offset; + classinfo *c; /* get stuff from the stack */ - ra = (u1 *) *((ptrint *) (sp + 3 * 4)); - o = (java_objectheader *) *((ptrint *) (sp + 2 * 4)); - mcode = *((u4 *) (sp + 1 * 4)); - uf = (unresolved_field *) *((ptrint *) (sp + 0 * 4)); - pv = (u1 *) *((ptrint *) (sp - 2 * 4)); - - /* calculate and set the new return address */ - - ra = ra - 4; - *((ptrint *) (sp + 3 * 4)) = (ptrint) ra; - - PATCHER_MONITORENTER; - - /* get the fieldinfo */ - - if (!(fi = helper_resolve_fieldinfo(uf))) { - PATCHER_MONITOREXIT; - - return false; - } - - /* check if the field's class is initialized */ + c = (classinfo *) pr->ref; - if (!fi->class->initialized) { - if (!initialize_class(fi->class)) { - PATCHER_MONITOREXIT; + /* check if the class is initialized */ + if (!(c->state & CLASS_INITIALIZED)) + if (!initialize_class(c)) return false; - } - } - - /* patch back original code */ - - *((u4 *) ra) = mcode; - - /* if we show disassembly, we have to skip the nop */ - - if (showdisassemble) - ra = ra + 4; - - /* get the offset from machine instruction */ - - offset = (s2) (*((u4 *) ra) & 0x0000ffff); - - /* patch the field value's address */ - *((ptrint *) (pv + offset)) = (ptrint) &(fi->value); - - /* synchronize instruction cache */ - - asm_cacheflush(ra, 4); - - PATCHER_MARK_PATCHED_MONITOREXIT; + PATCH_BACK_ORIGINAL_MCODE; return true; } -/* patcher_get_putfield ******************************************************** +/* patcher_resolve_class ******************************************************* - Machine code: - - - 811f0014 lwz r8,20(r31) + Resolves a given unresolved_class pointer. This function does not + patch any data. *******************************************************************************/ -bool patcher_get_putfield(u1 *sp) +#ifdef ENABLE_VERIFIER +bool patcher_resolve_class(patchref_t *pr) { - u1 *ra; - java_objectheader *o; - u4 mcode; - unresolved_field *uf; - u1 *pv; - fieldinfo *fi; - - ra = (u1 *) *((ptrint *) (sp + 3 * 4)); - o = (java_objectheader *) *((ptrint *) (sp + 2 * 4)); - mcode = *((u4 *) (sp + 1 * 4)); - uf = (unresolved_field *) *((ptrint *) (sp + 0 * 4)); - pv = (u1 *) *((ptrint *) (sp - 2 * 4)); + unresolved_class *uc; - /* calculate and set the new return address */ - - ra = ra - 4; - *((ptrint *) (sp + 3 * 4)) = (ptrint) ra; - - PATCHER_MONITORENTER; + /* get stuff from the stack */ - /* get the fieldinfo */ + uc = (unresolved_class *) pr->ref; - if (!(fi = helper_resolve_fieldinfo(uf))) { - PATCHER_MONITOREXIT; + /* resolve the class and check subtype constraints */ + if (!resolve_class_eager_no_access_check(uc)) return false; - } - - /* patch back original code */ - *((u4 *) ra) = mcode; + PATCH_BACK_ORIGINAL_MCODE; - /* if we show disassembly, we have to skip the nop */ - - if (showdisassemble) - ra = ra + 4; - - /* patch the field's offset */ - - *((u4 *) ra) |= (s2) (fi->offset & 0x0000ffff); + return true; +} +#endif /* ENABLE_VERIFIER */ - /* if the field has type long, we need to patch the second move too */ - if (fi->type == TYPE_LNG) - *((u4 *) (ra + 4)) |= (s2) ((fi->offset + 4) & 0x0000ffff); +/* patcher_resolve_classref_to_classinfo *************************************** - /* synchronize instruction cache */ + ACONST: - asm_cacheflush(ra, 8); + + 806dffc4 lwz r3,-60(r13) + 81adffc0 lwz r13,-64(r13) + 7da903a6 mtctr r13 + 4e800421 bctrl - PATCHER_MARK_PATCHED_MONITOREXIT; - return true; -} + MULTIANEWARRAY: + + 808dffc0 lwz r4,-64(r13) + 38a10038 addi r5,r1,56 + 81adffbc lwz r13,-68(r13) + 7da903a6 mtctr r13 + 4e800421 bctrl -/* patcher_builtin_new ********************************************************* - Machine code: + ARRAYCHECKCAST: - 806dffc4 lwz r3,-60(r13) - - 81adffc0 lwz r13,-64(r13) + + 808dffd8 lwz r4,-40(r13) + 81adffd4 lwz r13,-44(r13) 7da903a6 mtctr r13 4e800421 bctrl *******************************************************************************/ -bool patcher_builtin_new(u1 *sp) +bool patcher_resolve_classref_to_classinfo(patchref_t *pr) { - u1 *ra; - java_objectheader *o; - u4 mcode; constant_classref *cr; - u1 *pv; + u1 *datap; classinfo *c; - s2 offset; /* get stuff from the stack */ - ra = (u1 *) *((ptrint *) (sp + 3 * 4)); - o = (java_objectheader *) *((ptrint *) (sp + 2 * 4)); - mcode = *((u4 *) (sp + 1 * 4)); - cr = (constant_classref *) *((ptrint *) (sp + 0 * 4)); - pv = (u1 *) *((ptrint *) (sp - 2 * 4)); - - /* calculate and set the new return address */ - - ra = ra - (4 + 4); - *((ptrint *) (sp + 3 * 4)) = (ptrint) ra; - - PATCHER_MONITORENTER; + cr = (constant_classref *) pr->ref; + datap = (u1 *) pr->datap; /* get the classinfo */ - if (!(c = helper_resolve_classinfo(cr))) { - PATCHER_MONITOREXIT; - + if (!(c = resolve_classref_eager(cr))) return false; - } - /* patch back original code */ - - *((u4 *) (ra + 4)) = mcode; - - /* get the offset from machine instruction */ - - offset = (s2) (*((u4 *) ra) & 0x0000ffff); + PATCH_BACK_ORIGINAL_MCODE; /* patch the classinfo pointer */ - *((ptrint *) (pv + offset)) = (ptrint) c; - - /* if we show disassembly, we have to skip the nop */ - - if (showdisassemble) - ra = ra + 4; + *((ptrint *) datap) = (ptrint) c; - /* get the offset from machine instruction */ + /* synchronize data cache */ - offset = (s2) (*((u4 *) (ra + 4)) & 0x0000ffff); + md_dcacheflush(datap, SIZEOF_VOID_P); - /* patch new function address */ - - *((ptrint *) (pv + offset)) = (ptrint) BUILTIN_new; + return true; +} - /* synchronize instruction cache */ - asm_cacheflush(ra + 4, 4); +/* patcher_resolve_classref_to_vftbl ******************************************* - PATCHER_MARK_PATCHED_MONITOREXIT; - - return true; -} + CHECKCAST (class): + + 81870000 lwz r12,0(r7) + 800c0014 lwz r0,20(r12) + 818dff78 lwz r12,-136(r13) -/* patcher_builtin_newarray **************************************************** - Machine code: + INSTANCEOF (class): - 808dffc8 lwz r4,-56(r13) - 81adffc4 lwz r13,-60(r13) - 7da903a6 mtctr r13 - 4e800421 bctrl + 817d0000 lwz r11,0(r29) + 818dff8c lwz r12,-116(r13) *******************************************************************************/ -bool patcher_builtin_newarray(u1 *sp) +bool patcher_resolve_classref_to_vftbl(patchref_t *pr) { - u1 *ra; - java_objectheader *o; - u4 mcode; constant_classref *cr; - u1 *pv; + u1 *datap; classinfo *c; - s2 offset; /* get stuff from the stack */ - ra = (u1 *) *((ptrint *) (sp + 3 * 4)); - o = (java_objectheader *) *((ptrint *) (sp + 2 * 4)); - mcode = *((u4 *) (sp + 1 * 4)); - cr = (constant_classref *) *((ptrint *) (sp + 0 * 4)); - pv = (u1 *) *((ptrint *) (sp - 2 * 4)); - - /* calculate and set the new return address */ - - ra = ra - 2 * 4; - *((ptrint *) (sp + 3 * 4)) = (ptrint) ra; - - PATCHER_MONITORENTER; - - /* get the classinfo */ + cr = (constant_classref *) pr->ref; + datap = (u1 *) pr->datap; - if (!(c = helper_resolve_classinfo(cr))) { - PATCHER_MONITOREXIT; + /* get the fieldinfo */ + if (!(c = resolve_classref_eager(cr))) return false; - } - - /* patch back original code */ - - *((u4 *) (ra + 4)) = mcode; - - /* get the offset from machine instruction */ - offset = (s2) (*((u4 *) ra) & 0x0000ffff); + PATCH_BACK_ORIGINAL_MCODE; - /* patch the class' vftbl pointer */ - - *((ptrint *) (pv + offset)) = (ptrint) c->vftbl; - - /* if we show disassembly, we have to skip the nop */ - - if (showdisassemble) - ra = ra + 4; - - /* get the offset from machine instruction */ - - offset = (s2) (*((u4 *) (ra + 4)) & 0x0000ffff); - - /* patch new function address */ - - *((ptrint *) (pv + offset)) = (ptrint) BUILTIN_newarray; + /* patch super class' vftbl */ - /* synchronize instruction cache */ + *((ptrint *) datap) = (ptrint) c->vftbl; - asm_cacheflush(ra, 4); + /* synchronize data cache */ - PATCHER_MARK_PATCHED_MONITOREXIT; + md_dcacheflush(datap, SIZEOF_VOID_P); return true; } -/* patcher_builtin_multianewarray ********************************************** +/* patcher_resolve_classref_to_flags ******************************************* - Machine code: + CHECKCAST/INSTANCEOF: - 38600002 li r3,2 - 808dffc0 lwz r4,-64(r13) - 38a10038 addi r5,r1,56 - 81adffbc lwz r13,-68(r13) - 7da903a6 mtctr r13 - 4e800421 bctrl + 818dff7c lwz r12,-132(r13) *******************************************************************************/ -bool patcher_builtin_multianewarray(u1 *sp) +bool patcher_resolve_classref_to_flags(patchref_t *pr) { - u1 *ra; - java_objectheader *o; - u4 mcode; constant_classref *cr; - u1 *pv; + u1 *datap; classinfo *c; - s2 offset; /* get stuff from the stack */ - ra = (u1 *) *((ptrint *) (sp + 3 * 4)); - o = (java_objectheader *) *((ptrint *) (sp + 2 * 4)); - mcode = *((u4 *) (sp + 1 * 4)); - cr = (constant_classref *) *((ptrint *) (sp + 0 * 4)); - pv = (u1 *) *((ptrint *) (sp - 2 * 4)); + cr = (constant_classref *) pr->ref; + datap = (u1 *) pr->datap; - /* calculate and set the new return address */ + /* get the fieldinfo */ - ra = ra - 4; - *((ptrint *) (sp + 3 * 4)) = (ptrint) ra; + if (!(c = resolve_classref_eager(cr))) + return false; - PATCHER_MONITORENTER; + PATCH_BACK_ORIGINAL_MCODE; - /* get the classinfo */ + /* patch class flags */ - if (!(c = helper_resolve_classinfo(cr))) { - PATCHER_MONITOREXIT; + *((s4 *) datap) = (s4) c->flags; - return false; - } + /* synchronize data cache */ - /* patch back original code */ + md_dcacheflush(datap, SIZEOF_VOID_P); - *((u4 *) ra) = mcode; + return true; +} - /* if we show disassembly, we have to skip the nop */ - if (showdisassemble) - ra = ra + 4; +/* patcher_resolve_native_function ********************************************* - /* get the offset from machine instruction */ + XXX - offset = (s2) (*((u4 *) (ra + 4)) & 0x0000ffff); +*******************************************************************************/ - /* patch the class' vftbl pointer */ +#if !defined(WITH_STATIC_CLASSPATH) +bool patcher_resolve_native_function(patchref_t *pr) +{ + methodinfo *m; + u1 *datap; + functionptr f; - *((ptrint *) (pv + offset)) = (ptrint) c->vftbl; + /* get stuff from the stack */ - /* synchronize instruction cache */ + m = (methodinfo *) pr->ref; + datap = (u1 *) pr->datap; + + /* resolve native function */ + + if (!(f = native_resolve_function(m))) + return false; + + PATCH_BACK_ORIGINAL_MCODE; - asm_cacheflush(ra, 4); + /* patch native function pointer */ - PATCHER_MARK_PATCHED_MONITOREXIT; + *((ptrint *) datap) = (ptrint) f; + + /* synchronize data cache */ + + md_dcacheflush(datap, SIZEOF_VOID_P); return true; } +#endif /* !defined(WITH_STATIC_CLASSPATH) */ -/* patcher_builtin_arraycheckcast ********************************************** +/* patcher_get_putstatic ******************************************************* Machine code: - 808dffd8 lwz r4,-40(r13) - 81adffd4 lwz r13,-44(r13) - 7da903a6 mtctr r13 - 4e800421 bctrl + 816dffc8 lwz r11,-56(r13) + 80ab0000 lwz r5,0(r11) *******************************************************************************/ -bool patcher_builtin_arraycheckcast(u1 *sp) +bool patcher_get_putstatic(patchref_t *pr) { - u1 *ra; - java_objectheader *o; - u4 mcode; - constant_classref *cr; - u1 *pv; - classinfo *c; - s2 offset; + u1 *ra; + unresolved_field *uf; + u1 *datap; + fieldinfo *fi; /* get stuff from the stack */ - ra = (u1 *) *((ptrint *) (sp + 3 * 4)); - o = (java_objectheader *) *((ptrint *) (sp + 2 * 4)); - mcode = *((u4 *) (sp + 1 * 4)); - cr = (constant_classref *) *((ptrint *) (sp + 0 * 4)); - pv = (u1 *) *((ptrint *) (sp - 2 * 4)); - - /* calculate and set the new return address */ - - ra = ra - 2 * 4; - *((ptrint *) (sp + 3 * 4)) = (ptrint) ra; - - PATCHER_MONITORENTER; - - /* get the classinfo */ + ra = (u1 *) pr->mpc; + uf = (unresolved_field *) pr->ref; + datap = (u1 *) pr->datap; - if (!(c = helper_resolve_classinfo(cr))) { - PATCHER_MONITOREXIT; + /* get the fieldinfo */ + if (!(fi = resolve_field_eager(uf))) return false; - } - - /* patch back original code */ - - *((u4 *) (ra + 4)) = mcode; - - /* get the offset from machine instruction */ - offset = (s2) (*((u4 *) ra) & 0x0000ffff); - - /* patch the class' vftbl pointer */ - - *((ptrint *) (pv + offset)) = (ptrint) c->vftbl; - - /* if we show disassembly, we have to skip the nop */ - - if (showdisassemble) - ra = ra + 4; - - /* get the offset from machine instruction */ + /* check if the field's class is initialized */ - offset = (s2) (*((u4 *) (ra + 4)) & 0x0000ffff); + if (!(fi->class->state & CLASS_INITIALIZED)) + if (!initialize_class(fi->class)) + return false; - /* patch new function address */ + PATCH_BACK_ORIGINAL_MCODE; - *((ptrint *) (pv + offset)) = (ptrint) BUILTIN_arraycheckcast; + /* patch the field value's address */ - /* synchronize instruction cache */ + *((intptr_t *) datap) = (intptr_t) fi->value; - asm_cacheflush(ra + 4, 4); + /* synchronize data cache */ - PATCHER_MARK_PATCHED_MONITOREXIT; + md_dcacheflush(datap, SIZEOF_VOID_P); return true; } -/* patcher_builtin_arrayinstanceof ********************************************* +/* patcher_get_putfield ******************************************************** Machine code: - 808dff50 lwz r4,-176(r13) - 81adff4c lwz r13,-180(r13) - 7da903a6 mtctr r13 - 4e800421 bctrl + 811f0014 lwz r8,20(r31) *******************************************************************************/ -bool patcher_builtin_arrayinstanceof(u1 *sp) +bool patcher_get_putfield(patchref_t *pr) { - u1 *ra; - java_objectheader *o; - u4 mcode; - constant_classref *cr; - u1 *pv; - classinfo *c; - s4 offset; - - /* get stuff from the stack */ - - ra = (u1 *) *((ptrint *) (sp + 3 * 4)); - o = (java_objectheader *) *((ptrint *) (sp + 2 * 4)); - mcode = *((u4 *) (sp + 1 * 4)); - cr = (constant_classref *) *((ptrint *) (sp + 0 * 4)); - pv = (u1 *) *((ptrint *) (sp - 2 * 4)); - - /* calculate and set the new return address */ - - ra = ra - 2 * 4; - *((ptrint *) (sp + 3 * 4)) = (ptrint) ra; - - PATCHER_MONITORENTER; + u1 *ra; + unresolved_field *uf; + fieldinfo *fi; + s2 disp; - /* get the classinfo */ + ra = (u1 *) pr->mpc; + uf = (unresolved_field *) pr->ref; - if (!(c = helper_resolve_classinfo(cr))) { - PATCHER_MONITOREXIT; + /* get the fieldinfo */ + if (!(fi = resolve_field_eager(uf))) return false; - } - - /* patch back original code */ - - *((u4 *) (ra + 4)) = mcode; - - /* get the offset from machine instruction */ - offset = (s2) (*((u4 *) ra) & 0x0000ffff); + PATCH_BACK_ORIGINAL_MCODE; - /* patch the class' vftbl pointer */ - - *((ptrint *) (pv + offset)) = (ptrint) c->vftbl; + /* if we show NOPs, we have to skip them */ - /* if we show disassembly, we have to skip the nop */ + if (opt_shownops) + ra = ra + 1 * 4; - if (showdisassemble) - ra = ra + 4; - - /* get the offset from machine instruction */ + /* patch the field's offset */ - offset = (s2) (*((u4 *) (ra + 4)) & 0x0000ffff); + if (IS_LNG_TYPE(fi->type)) { + /* If the field has type long, we have to patch two + instructions. But we have to check which instruction + is first. We do that with the offset of the first + instruction. */ - /* patch new function address */ + disp = *((u4 *) (ra + 0 * 4)); - *((ptrint *) (pv + offset)) = (ptrint) BUILTIN_arrayinstanceof; + if (disp == 4) { + *((u4 *) (ra + 0 * 4)) &= 0xffff0000; + *((u4 *) (ra + 0 * 4)) |= (s2) ((fi->offset + 4) & 0x0000ffff); + *((u4 *) (ra + 1 * 4)) |= (s2) ((fi->offset + 0) & 0x0000ffff); + } + else { + *((u4 *) (ra + 0 * 4)) |= (s2) ((fi->offset + 0) & 0x0000ffff); + *((u4 *) (ra + 1 * 4)) &= 0xffff0000; + *((u4 *) (ra + 1 * 4)) |= (s2) ((fi->offset + 4) & 0x0000ffff); + } + } + else + *((u4 *) (ra + 0 * 4)) |= (s2) (fi->offset & 0x0000ffff); /* synchronize instruction cache */ - asm_cacheflush(ra + 4, 4); - - PATCHER_MARK_PATCHED_MONITOREXIT; + md_icacheflush(ra + 0 * 4, 2 * 4); return true; } @@ -596,61 +420,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; - u4 mcode; unresolved_method *um; - u1 *pv; + u1 *datap; methodinfo *m; - s4 offset; /* get stuff from the stack */ - ra = (u1 *) *((ptrint *) (sp + 3 * 4)); - o = (java_objectheader *) *((ptrint *) (sp + 2 * 4)); - mcode = *((u4 *) (sp + 1 * 4)); - um = (unresolved_method *) *((ptrint *) (sp + 0 * 4)); - pv = (u1 *) *((ptrint *) (sp - 2 * 4)); - - /* calculate and set the new return address */ - - ra = ra - 4; - *((ptrint *) (sp + 3 * 4)) = (ptrint) ra; - - PATCHER_MONITORENTER; + um = (unresolved_method *) pr->ref; + datap = (u1 *) pr->datap; /* get the fieldinfo */ - if (!(m = helper_resolve_methodinfo(um))) { - PATCHER_MONITOREXIT; - + if (!(m = resolve_method_eager(um))) return false; - } - - /* patch back original code */ - - *((u4 *) ra) = mcode; - - /* if we show disassembly, we have to skip the nop */ - - if (showdisassemble) - ra = ra + 4; - /* get the offset from machine instruction */ - - offset = (s2) (*((u4 *) ra) & 0x0000ffff); + PATCH_BACK_ORIGINAL_MCODE; /* patch stubroutine */ - *((ptrint *) (pv + offset)) = (ptrint) m->stubroutine; - - /* synchronize instruction cache */ + *((ptrint *) datap) = (ptrint) m->stubroutine; - asm_cacheflush(ra, 4); + /* synchronize data cache */ - PATCHER_MARK_PATCHED_MONITOREXIT; + md_dcacheflush(datap, SIZEOF_VOID_P); return true; } @@ -668,55 +462,39 @@ bool patcher_invokestatic_special(u1 *sp) *******************************************************************************/ -bool patcher_invokevirtual(u1 *sp) +bool patcher_invokevirtual(patchref_t *pr) { u1 *ra; - java_objectheader *o; - u4 mcode; unresolved_method *um; methodinfo *m; + s4 disp; /* get stuff from the stack */ - ra = (u1 *) *((ptrint *) (sp + 3 * 4)); - o = (java_objectheader *) *((ptrint *) (sp + 2 * 4)); - mcode = *((u4 *) (sp + 1 * 4)); - um = (unresolved_method *) *((ptrint *) (sp + 0 * 4)); - - /* calculate and set the new return address */ - - ra = ra - 4; - *((ptrint *) (sp + 3 * 4)) = (ptrint) ra; - - PATCHER_MONITORENTER; + ra = (u1 *) pr->mpc; + um = (unresolved_method *) pr->ref; /* get the fieldinfo */ - if (!(m = helper_resolve_methodinfo(um))) { - PATCHER_MONITOREXIT; - + if (!(m = resolve_method_eager(um))) return false; - } - - /* patch back original code */ - *((u4 *) ra) = mcode; + PATCH_BACK_ORIGINAL_MCODE; - /* if we show disassembly, we have to skip the nop */ + /* if we show NOPs, we have to skip them */ - if (showdisassemble) - ra = ra + 4; + if (opt_shownops) + ra = ra + 1 * 4; /* patch vftbl index */ - *((s4 *) (ra + 4)) |= (s4) ((OFFSET(vftbl_t, table[0]) + - sizeof(methodptr) * m->vftblindex) & 0x0000ffff); + disp = (OFFSET(vftbl_t, table[0]) + sizeof(methodptr) * m->vftblindex); - /* synchronize instruction cache */ + *((s4 *) (ra + 1 * 4)) |= (disp & 0x0000ffff); - asm_cacheflush(ra, 2 * 4); + /* synchronize instruction cache */ - PATCHER_MARK_PATCHED_MONITOREXIT; + md_icacheflush(ra + 1 * 4, 1 * 4); return true; } @@ -735,379 +513,162 @@ bool patcher_invokevirtual(u1 *sp) *******************************************************************************/ -bool patcher_invokeinterface(u1 *sp) +bool patcher_invokeinterface(patchref_t *pr) { u1 *ra; - java_objectheader *o; - u4 mcode; unresolved_method *um; methodinfo *m; + s4 disp; /* get stuff from the stack */ - ra = (u1 *) *((ptrint *) (sp + 3 * 4)); - o = (java_objectheader *) *((ptrint *) (sp + 2 * 4)); - mcode = *((u4 *) (sp + 1 * 4)); - um = (unresolved_method *) *((ptrint *) (sp + 0 * 4)); - - /* calculate and set the new return address */ - - ra = ra - 4; - *((ptrint *) (sp + 3 * 4)) = (ptrint) ra; - - PATCHER_MONITORENTER; + ra = (u1 *) pr->mpc; + um = (unresolved_method *) pr->ref; /* get the fieldinfo */ - if (!(m = helper_resolve_methodinfo(um))) { - PATCHER_MONITOREXIT; - + if (!(m = resolve_method_eager(um))) return false; - } - - /* patch back original code */ - *((u4 *) ra) = mcode; + PATCH_BACK_ORIGINAL_MCODE; - /* if we show disassembly, we have to skip the nop */ + /* if we show NOPs, we have to skip them */ - if (showdisassemble) - ra = ra + 4; + if (opt_shownops) + ra = ra + 1 * 4; /* patch interfacetable index */ - *((s4 *) (ra + 1 * 4)) |= (s4) ((OFFSET(vftbl_t, interfacetable[0]) - - sizeof(methodptr*) * m->class->index) & 0x0000ffff); - - /* patch method offset */ - - *((s4 *) (ra + 2 * 4)) |= - (s4) ((sizeof(methodptr) * (m - m->class->methods)) & 0x0000ffff); - - /* synchronize instruction cache */ - - asm_cacheflush(ra, 3 * 4); - - PATCHER_MARK_PATCHED_MONITOREXIT; - - return true; -} - - -/* patcher_checkcast_instanceof_flags ****************************************** - - Machine code: - - - -*******************************************************************************/ - -bool patcher_checkcast_instanceof_flags(u1 *sp) -{ - u1 *ra; - java_objectheader *o; - u4 mcode; - constant_classref *cr; - u1 *pv; - classinfo *c; - s2 offset; - - /* get stuff from the stack */ - - ra = (u1 *) *((ptrint *) (sp + 3 * 4)); - o = (java_objectheader *) *((ptrint *) (sp + 2 * 4)); - mcode = *((u4 *) (sp + 1 * 4)); - cr = (constant_classref *) *((ptrint *) (sp + 0 * 4)); - pv = (u1 *) *((ptrint *) (sp - 2 * 4)); - - /* calculate and set the new return address */ + disp = OFFSET(vftbl_t, interfacetable[0]) - + sizeof(methodptr*) * m->class->index; - ra = ra - 4; - *((ptrint *) (sp + 3 * 4)) = (ptrint) ra; + /* XXX TWISTI: check displacement */ - PATCHER_MONITORENTER; + *((s4 *) (ra + 1 * 4)) |= (disp & 0x0000ffff); - /* get the fieldinfo */ - - if (!(c = helper_resolve_classinfo(cr))) { - PATCHER_MONITOREXIT; + /* patch method offset */ - return false; - } + disp = sizeof(methodptr) * (m - m->class->methods); - /* patch back original code */ + /* XXX TWISTI: check displacement */ - *((u4 *) ra) = mcode; + *((s4 *) (ra + 2 * 4)) |= (disp & 0x0000ffff); /* synchronize instruction cache */ - asm_cacheflush(ra, 4); - - /* if we show disassembly, we have to skip the nop */ - - if (showdisassemble) - ra = ra + 4; - - /* get the offset from machine instruction */ - - offset = (s2) (*((u4 *) ra) & 0x0000ffff); - - /* patch class flags */ - - *((s4 *) (pv + offset)) = (s4) c->flags; - - PATCHER_MARK_PATCHED_MONITOREXIT; + md_icacheflush(ra + 1 * 4, 2 * 4); return true; } -/* patcher_checkcast_instanceof_interface ************************************** +/* patcher_checkcast_interface ************************************************* Machine code: + 81870000 lwz r12,0(r7) + 800c0010 lwz r0,16(r12) + 34000000 addic. r0,r0,0 + 41810008 bgt- 0x014135d8 + 83c00003 lwz r30,3(0) + 800c0000 lwz r0,0(r12) *******************************************************************************/ -bool patcher_checkcast_instanceof_interface(u1 *sp) +bool patcher_checkcast_interface(patchref_t *pr) { u1 *ra; - java_objectheader *o; - u4 mcode; constant_classref *cr; classinfo *c; + s4 disp; /* get stuff from the stack */ - ra = (u1 *) *((ptrint *) (sp + 3 * 4)); - o = (java_objectheader *) *((ptrint *) (sp + 2 * 4)); - mcode = *((u4 *) (sp + 1 * 4)); - cr = (constant_classref *) *((ptrint *) (sp + 0 * 4)); - - /* calculate and set the new return address */ - - ra = ra - 4; - *((ptrint *) (sp + 3 * 4)) = (ptrint) ra; - - PATCHER_MONITORENTER; + ra = (u1 *) pr->mpc; + cr = (constant_classref *) pr->ref; /* get the fieldinfo */ - if (!(c = helper_resolve_classinfo(cr))) { - PATCHER_MONITOREXIT; - + if (!(c = resolve_classref_eager(cr))) return false; - } - - /* patch back original code */ - *((u4 *) ra) = mcode; + PATCH_BACK_ORIGINAL_MCODE; - /* if we show disassembly, we have to skip the nop */ + /* if we show NOPs, we have to skip them */ - if (showdisassemble) - ra = ra + 4; + if (opt_shownops) + ra = ra + 1 * 4; /* patch super class index */ - *((s4 *) (ra + 2 * 4)) |= (s4) (-(c->index) & 0x0000ffff); - - *((s4 *) (ra + 4 * 4)) |= (s4) ((OFFSET(vftbl_t, interfacetable[0]) - - c->index * sizeof(methodptr*)) & 0x0000ffff); - - /* synchronize instruction cache */ - - asm_cacheflush(ra, 5 * 4); - - PATCHER_MARK_PATCHED_MONITOREXIT; - - return true; -} - - -/* patcher_checkcast_class ***************************************************** - - Machine code: - - - -*******************************************************************************/ - -bool patcher_checkcast_class(u1 *sp) -{ - u1 *ra; - java_objectheader *o; - u4 mcode; - constant_classref *cr; - u1 *pv; - classinfo *c; - s2 offset; - - /* get stuff from the stack */ - - ra = (u1 *) *((ptrint *) (sp + 3 * 4)); - o = (java_objectheader *) *((ptrint *) (sp + 2 * 4)); - mcode = *((u4 *) (sp + 1 * 4)); - cr = (constant_classref *) *((ptrint *) (sp + 0 * 4)); - pv = (u1 *) *((ptrint *) (sp - 2 * 4)); - - /* calculate and set the new return address */ + disp = -(c->index); - ra = ra - 4; - *((ptrint *) (sp + 3 * 4)) = (ptrint) ra; + *((s4 *) (ra + 2 * 4)) |= (disp & 0x0000ffff); - PATCHER_MONITORENTER; + disp = OFFSET(vftbl_t, interfacetable[0]) - c->index * sizeof(methodptr*); - /* get the fieldinfo */ - - if (!(c = helper_resolve_classinfo(cr))) { - PATCHER_MONITOREXIT; - - return false; - } - - /* patch back original code */ - - *((u4 *) ra) = mcode; + *((s4 *) (ra + 5 * 4)) |= (disp & 0x0000ffff); /* synchronize instruction cache */ - asm_cacheflush(ra, 4); - - /* if we show disassembly, we have to skip the nop */ - - if (showdisassemble) - ra = ra + 4; - - /* get the offset from machine instruction */ - - offset = (s2) (*((u4 *) (ra + 2 * 4)) & 0x0000ffff); - - /* patch super class' vftbl */ - - *((ptrint *) (pv + offset)) = (ptrint) c->vftbl; - - PATCHER_MARK_PATCHED_MONITOREXIT; + md_icacheflush(ra + 2 * 4, 4 * 4); return true; } -/* patcher_instanceof_class **************************************************** +/* patcher_instanceof_interface ************************************************ Machine code: + 81870000 lwz r12,0(r7) + 800c0010 lwz r0,16(r12) + 34000000 addic. r0,r0,0 + 41810008 bgt- 0x014135d8 + 83c00003 lwz r30,3(0) + 800c0000 lwz r0,0(r12) *******************************************************************************/ -bool patcher_instanceof_class(u1 *sp) +bool patcher_instanceof_interface(patchref_t *pr) { u1 *ra; - java_objectheader *o; - u4 mcode; constant_classref *cr; - u1 *pv; classinfo *c; - s2 offset; + s4 disp; /* get stuff from the stack */ - ra = (u1 *) *((ptrint *) (sp + 3 * 4)); - o = (java_objectheader *) *((ptrint *) (sp + 2 * 4)); - mcode = *((u4 *) (sp + 1 * 4)); - cr = (constant_classref *) *((ptrint *) (sp + 0 * 4)); - pv = (u1 *) *((ptrint *) (sp - 2 * 4)); - - /* calculate and set the new return address */ - - ra = ra - 4; - *((ptrint *) (sp + 3 * 4)) = (ptrint) ra; - - PATCHER_MONITORENTER; + ra = (u1 *) pr->mpc; + cr = (constant_classref *) pr->ref; /* get the fieldinfo */ - if (!(c = helper_resolve_classinfo(cr))) { - PATCHER_MONITOREXIT; - + if (!(c = resolve_classref_eager(cr))) return false; - } - - /* patch back original code */ - - *((u4 *) ra) = mcode; - - /* synchronize instruction cache */ - - asm_cacheflush(ra, 4); - - /* if we show disassembly, we have to skip the nop */ - - if (showdisassemble) - ra = ra + 4; - - /* get the offset from machine instruction */ - - offset = (s2) (*((u4 *) (ra + 1 * 4)) & 0x0000ffff); - - /* patch super class' vftbl */ - - *((ptrint *) (pv + offset)) = (ptrint) c->vftbl; - - PATCHER_MARK_PATCHED_MONITOREXIT; - return true; -} - - -/* patcher_clinit ************************************************************** - - XXX - -*******************************************************************************/ - -bool patcher_clinit(u1 *sp) -{ - u1 *ra; - java_objectheader *o; - u4 mcode; - classinfo *c; - - /* get stuff from the stack */ + PATCH_BACK_ORIGINAL_MCODE; - ra = (u1 *) *((ptrint *) (sp + 3 * 4)); - o = (java_objectheader *) *((ptrint *) (sp + 2 * 4)); - mcode = *((u4 *) (sp + 1 * 4)); - c = (classinfo *) *((ptrint *) (sp + 0 * 4)); + /* if we show NOPs, we have to skip them */ - /* calculate and set the new return address */ + if (opt_shownops) + ra = ra + 1 * 4; - ra = ra - 4; - *((ptrint *) (sp + 3 * 4)) = (ptrint) ra; - - PATCHER_MONITORENTER; - - /* check if the class is initialized */ + /* patch super class index */ - if (!c->initialized) { - if (!initialize_class(c)) { - PATCHER_MONITOREXIT; + disp = -(c->index); - return false; - } - } + *((s4 *) (ra + 2 * 4)) |= (disp & 0x0000ffff); - /* patch back original code */ + disp = OFFSET(vftbl_t, interfacetable[0]) - c->index * sizeof(methodptr*); - *((u4 *) ra) = mcode; + *((s4 *) (ra + 4 * 4)) |= (disp & 0x0000ffff); /* synchronize instruction cache */ - asm_cacheflush(ra, 4); - - PATCHER_MARK_PATCHED_MONITOREXIT; + md_icacheflush(ra + 2 * 4, 3 * 4); return true; }