📄 classinfo.java
字号:
if (cpoolUsed.contains(ii)) return; cpoolUsed.add(ii); if (len>1) { // add a dummy entry for a long or double constant cpoolUsed.add(null); } } /** * @param cp */ public void resolveCPool(ConstantPool cp) { Constant[] ca = cp.getConstantPool(); cpoolArry = new int[cpoolUsed.size()]; cpoolComments = new String[ca.length];// System.out.println(clazz.getClassName()+" cpool "+cpoolUsed); for (int i=0; i<ca.length; ++i) { Constant co = ca[i]; Integer idx = new Integer(i); // pos is the new position in the reduced constant pool // idx is the position in the 'original' unresolved cpool int pos = cpoolUsed.indexOf(idx); if (pos!=-1) { boolean isInterface = false;// System.out.println("cpool@"+pos+" = orig_cp@"+i+" "+co); switch(co.getTag()) { case Constants.CONSTANT_Integer: cpoolArry[pos] = ((ConstantInteger) co).getBytes(); cpoolComments[pos] = "Integer"; break; case Constants.CONSTANT_Long: long lval = ((ConstantLong) co).getBytes(); // store LOW, HIGH words in this order int loW = (new Long(0xFFFFFFFF & lval)).intValue(); int hiW = (new Long(lval >>> 32)).intValue(); cpoolArry[pos] = hiW; cpoolArry[pos+1] = loW; cpoolComments[pos] = "Long: "+lval; cpoolComments[pos+1] = ""; break; case Constants.CONSTANT_Float: float fval = ((ConstantFloat) co).getBytes(); cpoolArry[pos] = Float.floatToRawIntBits(fval); cpoolComments[pos] = "Float: "+fval; break; case Constants.CONSTANT_String: String str = ((ConstantString) co).getBytes(cp); StringInfo si = StringInfo.getStringInfo(str); cpoolArry[pos] = StringInfo.stringTableAddress+si.getAddress(); cpoolComments[pos] = "String: "+si.getSaveString(); break; case Constants.CONSTANT_Class: String clname = ((ConstantClass) co).getBytes(cp).replace('/','.'); ClassInfo clinfo = (ClassInfo) mapClassNames.get(clname); if (clinfo==null) { cpoolComments[pos] = "Problem with class: "+clname; continue; } cpoolArry[pos] = clinfo.classRefAddress; cpoolComments[pos] = "Class: "+clname; break; case Constants.CONSTANT_InterfaceMethodref: isInterface = true; case Constants.CONSTANT_Methodref: // find the class for this method int mclidx; if (isInterface) { mclidx = ((ConstantInterfaceMethodref) co).getClassIndex(); } else { mclidx = ((ConstantMethodref) co).getClassIndex(); } ConstantClass mcl = (ConstantClass) cp.getConstant(mclidx); // the method has "/" instead of ".", fix that // now get the signature too... String mclname = mcl.getBytes(cp).replace('/','.'); int sigidx; if (isInterface) { sigidx = ((ConstantInterfaceMethodref) co).getNameAndTypeIndex(); } else { sigidx = ((ConstantMethodref) co).getNameAndTypeIndex(); } ConstantNameAndType signt = (ConstantNameAndType) cp.getConstant(sigidx); String sigstr = signt.getName(cp)+signt.getSignature(cp); // now find the address of the method struct! ClassInfo clinf = (ClassInfo) mapClassNames.get(mclname); if (clinf==null) { // probably a reference to Native - a class that // is NOT present in the application. // we could avoid this by not adding method refs to // Native in our reduced cpool. cpoolArry[pos] = 0; cpoolComments[pos] = "static "+mclname+"."+sigstr; break; } MethodInfo minf = clinf.getVTMethodInfo(sigstr); if (minf==null) { System.out.println("Error: Method "+sigstr+" not found."); System.out.println("Invoked by "+clazz.getClassName()); System.exit(1); } if(minf.method.isStatic() || // <init> and privat methods are called with invokespecial // which mapps in jvm.asm to invokestatic minf.method.isPrivate() || sigstr.charAt(0)=='<' ) { // for static methods a direct pointer to the // method struct cpoolArry[pos] = minf.structAddress; cpoolComments[pos] = "static, special or private "+clinf.clazz.getClassName()+ "."+minf.methodId; } else { // as Flavius correctly comments: // TODO: CHANGE THIS TO A MORE CONSISTENT FORMAT... // extract the objref! for some reason the microcode needs -1 here...weird // that's for simple virtual methods int vpos = minf.vtindex; String comment = "virtual"; if (isInterface) { comment = "interface"; for (int j=0; j<listIT.size(); ++j) { IT it = (IT) listIT.get(j); if (it.key.equals(minf.methodId)) { vpos = j; break; } } // offest in interface table // index plus number of arguments (without this!) cpoolArry[pos] = (vpos<<8) + (minf.margs-1); } else { // offest in method table // (index*2) plus number of arguments (without this!) cpoolArry[pos] = (vpos*METH_STR<<8) + (minf.margs-1); } cpoolComments[pos] = comment+" index: "+vpos+ " args: "+minf.margs+" "+clinf.clazz.getClassName()+ "."+minf.methodId; } break; case Constants.CONSTANT_Fieldref: int fidx = ((ConstantFieldref) co).getClassIndex(); ConstantClass fcl = (ConstantClass) cp.getConstant(fidx); String fclname = fcl.getBytes(cp).replace('/','.'); // got the class name sigidx = ((ConstantFieldref) co).getNameAndTypeIndex(); signt = (ConstantNameAndType) cp.getConstant(sigidx); sigstr = signt.getName(cp)+signt.getSignature(cp); clinf = (ClassInfo) mapClassNames.get(fclname); int j; String comment = ""; boolean found = false; while (!found) { for (j=0; j<clinf.clft.len; ++j) { if (clinf.clft.key[j].equals(sigstr)) { found = true; if (clinf.clft.isStatic[j]) { comment = "static "; } // for static fields a direct pointer to the // static field cpoolArry[pos] = clinf.clft.idx[j]; cpoolComments[pos] = comment+clinf.clazz.getClassName()+ "."+sigstr; break; } } if (!found) { clinf = clinf.superClass; if (clinf==null) { System.out.println("Error: field "+fclname+"."+sigstr+" not found!"); break; } } } break; default: System.out.println("TODO: cpool@"+pos+" = orig_cp@"+i+" "+co); cpoolComments[pos] = "Problem with: "+co; } } } }/* from JCC JOPWriter * * if (mi.isStaticMember() || // <init> and privat methods are called with invokespecial // which mapps in jvm.asm to invokestatic prettyName(mi).charAt(0)=='<' || (mi.access & Const.ACC_PRIVATE)!=0) { out.print((cla.mtab+i*METH_STR)+",");out.print("\t//\tstatic, special or private"); } else { out.print(((i*2<<8)+mi.argsSize-1)+",");out.print("\t//\tvirtual index: "+i+" args: "+mi.argsSize); }*/ public void dumpStaticFields(PrintWriter out, boolean ref) { int i, addr; if (ref) { addr = staticRefVarAddress; } else { addr = staticValueVarAddress; } out.println("//"); out.println("//\t"+addr+": "+clazz.getClassName()+ " static "+(ref ? "reference " : " ")+"fields"); out.println("//"); for (i=0; i<clft.len; ++i) { if (clft.isStatic[i]) { if (clft.isReference[i]==ref) { if (clft.size[i]==1) { out.print("\t\t0,"); } else { out.print("\t\t0, 0,"); } out.println("\t//\t"+clft.idx[i]+": "+clft.key[i]); } } } } public void dump(PrintWriter out) { int i; out.println("//"); out.println("//\t"+classRefAddress+": "+clazz.getClassName()); out.println("//"); out.println("\t\t"+instSize+",\t//\tinstance size"); for (i=0; i<clft.len; ++i) { if (!clft.isStatic[i]) { out.println("\t\t\t\t//\t"+clft.idx[i]+" "+clft.key[i]); } } if (instSize>31) { System.err.println("Error: Object of "+clazz.getClassName()+" to big!"); System.exit(-1); } out.println("\t\t"+instGCinfo+",\t//\tinstance GC info"); String supname = "null"; if (superClass!=null) { supname = superClass.clazz.getClassName(); } out.println("\t\t\t//\tTODO: pointer to super class - "+supname); out.println("\t\t"+iftableAddress+",\t//\tpointer to interface table"); out.println("//"); out.println("//\t"+methodsAddress+": "+clazz.getClassName()+ " method table"); out.println("//"); int addr = methodsAddress; for(i=0; i < clvt.len; i++) { clvt.mi[i].dumpMethodStruct(out, addr); addr += METH_STR; } out.println(); out.println("\t\t"+classRefAddress+",\t//\tpointer back to class struct (cp-1)"); out.println(); out.println("//"); out.println("//\t"+cpoolAddress+": "+clazz.getClassName()+" constants"); out.println("//"); // constant pool length includes the length field // same is true for the index in the bytecodes: // The lowest constant has indes 1. out.println("\t\t"+(cpoolArry.length+1)+",\t//\tconst pool length"); out.println(); for (i=0; i<cpoolArry.length; ++i) { out.println("\t\t"+cpoolArry[i]+",\t//\t"+cpoolComments[i]); } if (iftableAddress!=0) { out.println("//"); out.println("//\t"+iftableAddress+": "+clazz.getClassName()+ " interface table"); out.println("//"); out.println("//\tTODO: is it enough to use methodId as key???"); out.println("//"); for (i=0; i<listIT.size(); ++i) { IT it = (IT) listIT.get(i); int j; for (j = 0; j < clvt.len; j++) { if (clvt.key[j].equals(it.key)) { break; } } if (j!=clvt.len) { out.print("\t\t"+(methodsAddress+j*METH_STR)+","); } else { out.print("\t\t"+0+",\t"); } out.println("\t//\t"+it.meth.methodId); } } } /** * @param className * @return */ public static ClassInfo getClassInfo(String className) { return (ClassInfo) mapClassNames.get(className); } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -