📄 codeblock.java
字号:
protected static final int brLOADNatCl = 6; // Set from the FieldRef table slot: ClassRef cr protected static final int brCLREFLOAD = 7; // Set to the method entry point plus the offset: long offs protected static final int brLOADCodeRel = 8; // Initialize a switch address table: long swtaddr protected static final int brINITSwitchTable = 9; // Set to the address where the given jvm pc starts: long offs protected static final int brLOADCodeAbs = 10; // Set to the address where the given label starts: long offs protected static final int brLOADCodeLbl = 11; // Overwrite the code at address with provided code: byte [] codeseq protected static final int brOverWriteCode = 12; // Find the address of a dynamically loaded native method protected static final int brLOADDynNative = 13; private BackpatchInfo bpinfo; abstract byte [] UNIMP (int codeval); abstract byte [] NOP (); abstract byte [] RELATIVE_CALL (int offs); abstract byte [] RELATIVE_JUMP (int offs); abstract byte [] LOAD_REG (int val, Object reg); protected byte[] evalBrCALL (int roffs) { return RELATIVE_CALL (roffs); } protected byte[] evalBrJUMP (int roffs) { return RELATIVE_JUMP (roffs); } protected byte[] evalBrLOAD (int roffs, Object reg) { return LOAD_REG (roffs, reg); } protected byte[] evalBrFIELDLOAD (int v, Object reg) { return LOAD_REG (v, reg); } protected byte[] evalBrACALL (int roffs) { return RELATIVE_CALL (roffs); } protected byte[] evalBrLOADNatCl (int v, Object reg) { return LOAD_REG (v, reg); } protected byte[] evalBrCLREFLOAD (int v, Object reg) { return LOAD_REG (v, reg); } protected byte[] evalBrLOADCodeRel (int v, Object reg) { return LOAD_REG (v, reg); } protected byte[] evalBrLOADCodeAbs (int v, Object reg) { return LOAD_REG (v, reg); } protected byte[] evalBrLOADCodeLbl (int v, Object reg) { return LOAD_REG (v, reg); } void doBackPatch (BackpatchInfo bpi) { long lpc; // Address of program counter for instruction int toffs; // Target offset within code buffer FieldRef fr; // Field reference Field fd; // Field value Method mt; // Method value long addr; // Generic address int iv; // Generic integer Class cl; // Class value ClassRef cr; // Class reference// System.err.println ("Resolving backpatch:" + bpi); if (null != bpi.or) { if (bpi.or instanceof FieldRef) { fr = (FieldRef) bpi.or; if (! fr.isResolved ()) {// System.out.println ("CodeBlock.backpatchInfo: Resolving field " + fr); cr = (ClassRef) fr.cl; if (! cr.isResolved (codeClassLoader)) { Resolve.resolveClassRef (cr, codeClassLoader); } cl = cr.getRefClass (codeClassLoader); fr.resolveWith (ClassRT.getClassData (cl)); if (! fr.isResolved()) { throw new InternalError ("CodeBlock.backpatchInfo: Resolution of field " + fr + " failed"); } } } else if (bpi.or instanceof ClassRef) { cr = (ClassRef) bpi.or; if (! cr.isResolved (codeClassLoader)) { /* Resolve this relative to the whosit that loaded the * class this method belongs to. */ Resolve.resolveClassRef (cr, codeClassLoader); if (! cr.isResolved(codeClassLoader)) { throw new InternalError ("CodeBlock.backpatchInfo: Resolution of class " + cr + " failed"); } } } else if ((bpi.or instanceof byte[]) || ((bpi.or instanceof Method) && (brLOADDynNative == bpi.brtype))) { /* don't need to do anything */ } else { throw new InternalError ("CodeBlock.backpatchInfo: Unrecognized object ref: " + bpi.or.getClass().getName ()); } } switch (bpi.brtype) { case brCALL: if (null == bpi.or) { throw new InternalError ("Call is missing target reference"); } fr = (FieldRef) bpi.or; if (! fr.isResolved ()) { throw new InternalError ("brCALL: FieldRef not resolved"); } fd = fr.getField(); mt = (Method) fd.tableObj; if (null != mt) { /* We generated the code for this, so there had better * be a mt.mtcode object with what we need in it. */ if (null == mt.mtcode) { throw new InternalError ("Method does not have code information"); } addr = mt.mtcode.getEntryPoint (); } else { /* This is a native function loaded from a library? * See if we can grab what we need from that. */ fr = (FieldRef) bpi.or; addr = ClassRT.getMethodAddr (fr.cl.getRefClass (codeClassLoader), fd); } if (0 == addr) { throw new UnsatisfiedLinkError ("Method " + fr + " does not have code entrypoint."); } lpc = bpi.loffs + method.mtcode.getMethodEntry (); if (jumpFromNextInstr) { lpc += bpi.inseqlen; } storeByteArray (evalBrCALL ((int)(addr - lpc)), bpi.loffs); break; case brJUMP: if (-1 == bpi.lv) { toffs = getEpilogOffs (); } else { toffs = instrToByteOffs [method.lblmap [(int) bpi.lv]]; } lpc = bpi.loffs; if (jumpFromNextInstr) { lpc += bpi.inseqlen; } storeByteArray (evalBrJUMP ((int) (toffs - lpc)), bpi.loffs); break; case brLOAD: fr = (FieldRef) bpi.or; if (! fr.isResolved ()) { throw new InternalError ("brLOAD: FieldRef not resolved"); } fd = fr.getField (); addr = ClassRT.getClassVarAddr (fr.cl.getRefClass (codeClassLoader), fd.tableslot); storeByteArray (evalBrLOAD ((int)addr, bpi.treg), bpi.loffs); break; case brACALL: /* Generate a call to the function at the provided absolute * address */ addr = bpi.lv; lpc = method.mtcode.getMethodEntry (); if (0 == lpc) { throw new UnsatisfiedLinkError ("Method " + method + " does not have code entrypoint."); } lpc += bpi.loffs; if (jumpFromNextInstr) { lpc += bpi.inseqlen; } storeByteArray (evalBrACALL ((int) (addr - lpc)), bpi.loffs); break; case brFIELDLOAD: /* Load the tableslot value from the reference */ fr = (FieldRef) bpi.or; if (! fr.isResolved ()) { throw new InternalError ("brFIELDLOAD: FieldRef not resolved"); } fd = fr.getField(); iv = fd.tableslot; storeByteArray (evalBrFIELDLOAD (iv, bpi.treg), bpi.loffs); break; case brCLREFLOAD: /* Load the class reference value from the reference */ cr = (ClassRef) bpi.or; if (! cr.isResolved (codeClassLoader)) { throw new InternalError ("brCLREFLOAD: ClassRef not resolved"); } cl = cr.getRefClass(codeClassLoader); if (null == cl) { throw new UnsatisfiedLinkError ("Class " + cr.name + " unresolved."); } iv = (int) CodeGen.getNativeObjectAddr (cl); storeByteArray (evalBrCLREFLOAD (iv, bpi.treg), bpi.loffs); break; case brLOADCodeRel: storeByteArray (evalBrLOADCodeRel ((int) (bpi.lv + mtentry), bpi.treg), bpi.loffs); break; case brLOADCodeAbs: toffs = (int) (mtentry + instrToByteOffs [method.pcmap [(int) bpi.lv]]); storeByteArray (evalBrLOADCodeAbs (toffs, bpi.treg), bpi.loffs); break; case brLOADCodeLbl: toffs = (int) (mtentry + instrToByteOffs [method.lblmap [(int) bpi.lv]]); storeByteArray (evalBrLOADCodeLbl (toffs, bpi.treg), bpi.loffs); break; case brINITSwitchTable: /* Store into the switch table target addresses, or keys * and targets, depending on switch type. */ addr = bpi.lv; if (Opcode.TBLSW == bpi.ins.opcode.code) { /* Tableswitch: store sequence of addresses */ iv = 1 + bpi.ins.more [2] - bpi.ins.more [1]; for (int i = 0; i < iv; i++) { CodeGen.pokeInt (addr, (int) (mtentry + instrToByteOffs [method.pcmap [bpi.ins.more[3+i]]])); addr += 4; } } else { if (Opcode.LKPSW != bpi.ins.opcode.code) { throw new InternalError ("brINITSwitchTable on non-switch instruction"); } for (int i = 0; i < bpi.ins.more [1]; i++) { CodeGen.pokeInt (addr, bpi.ins.more [2+2*i]); CodeGen.pokeInt (addr+4, (int) (mtentry + instrToByteOffs [method.pcmap [bpi.ins.more[3+2*i]]])); addr += 8; } } break; case brLOADNatCl: /* Load a pointer to the native "struct class *" class * structure of an object or class reference */ if (bpi.or instanceof FieldRef) { fr = (FieldRef) bpi.or; if (! fr.isResolved ()) { throw new InternalError ("brLOADNatCl: FieldRef not resolved"); } cr = fr.cl; fd = fr.getField (); } else if (bpi.or instanceof ClassRef) { cr = (ClassRef) bpi.or; } else { throw new InternalError ("Invalid type for brLOADNatCl: " + bpi.or); } if (! cr.isResolved (codeClassLoader)) { throw new InternalError ("brLOADNatCl: ClassRef not resolved"); } addr = ClassRT.getNativeClass (cr.getRefClass (codeClassLoader)); if (0 == addr) { throw new UnsatisfiedLinkError ("Class " + cr.name + " unresolved."); } storeByteArray (evalBrLOADNatCl ((int)addr, bpi.treg), bpi.loffs); break; case brOverWriteCode: storeByteArray ((byte []) bpi.or, bpi.loffs); break; case brLOADDynNative: mt = (Method) bpi.or; fd = mt.fl; addr = CodeGen.getNativeSymbolAddress (fd.cname); if (0 == addr) { throw new UnsatisfiedLinkError ("Native method " + fd.cname + " (from " + mt.cl.name + "." + fd.name + " not resolved"); } /** !!ToDo!! This is _extremely_ unstable. What it is is, * we're using "mtentry" as both the entry point, and the * start of a buffer into which we write code. Thing * is, if this native method doesn't have any sort of * preserved wrapper---i.e., it's not synchronized---we * want to set the mtentry to the real address of the * function. But we have to make damned sure that nobody * then uses mtentry as the destination of where to
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -