new code analyzer interface

canonize references: map to exact field class and static method class


git-svn-id: https://svn.code.sf.net/p/jode/code/trunk@1010 379699f6-c40d-0410-875b-85095c16579e
stable
jochen 25 years ago
parent 3b609b2f82
commit 77e3f4f9b7
  1. 83
      jode/jode/obfuscator/ConstantAnalyzer.java

@ -57,10 +57,11 @@ import jode.util.Iterator;
*/
public class ConstantAnalyzer implements Opcodes, CodeAnalyzer {
boolean working;
MethodIdentifier m;
BytecodeInfo bytecode;
Map constInfos;
BytecodeInfo bytecode;
Identifier listener;
private static ConstantRuntimeEnvironment runtime
= new ConstantRuntimeEnvironment();
@ -410,9 +411,7 @@ public class ConstantAnalyzer implements Opcodes, CodeAnalyzer {
private static ConstantInfo unknownConstInfo = new ConstantInfo();
public ConstantAnalyzer(BytecodeInfo code, MethodIdentifier method) {
this.bytecode = code;
this.m = method;
public ConstantAnalyzer() {
}
public void mergeInfo(Instruction instr,
@ -425,6 +424,50 @@ public class ConstantAnalyzer implements Opcodes, CodeAnalyzer {
((StackLocalInfo)instr.tmpInfo).merge(info);
}
public Identifier canonizeReference(Instruction instr) {
Reference ref = (Reference) instr.objData;
Identifier ident = Main.getClassBundle().getIdentifier(ref);
String clName = ref.getClazz();
String realClazzName;
if (ident != null) {
ClassIdentifier clazz = (ClassIdentifier)ident.getParent();
realClazzName = "L" + (clazz.getFullName()
.replace('.', '/')) + ";";
} else {
/* We have to look at the ClassInfo's instead, to
* point to the right method.
*/
ClassInfo clazz;
if (clName.charAt(0) == '[') {
/* Arrays don't define new methods (well clone(),
* but that can be ignored).
*/
clazz = ClassInfo.javaLangObject;
} else {
clazz = ClassInfo.forName
(clName.substring(1, clName.length()-1)
.replace('/','.'));
}
while (clazz != null
&& clazz.findMethod(ref.getName(),
ref.getType()) == null)
clazz = clazz.getSuperclass();
if (clazz == null) {
GlobalOptions.err.println("WARNING: Can't find reference: "
+ref);
realClazzName = clName;
} else
realClazzName = "L" + clazz.getName().replace('.', '/') + ";";
}
if (!realClazzName.equals(ref.getClazz())) {
ref = Reference.getReference(realClazzName,
ref.getName(), ref.getType());
instr.objData = ref;
}
return ident;
}
public void handleReference(Reference ref, boolean isVirtual) {
String clName = ref.getClazz();
/* Don't have to reach array methods */
@ -1135,10 +1178,9 @@ public class ConstantAnalyzer implements Opcodes, CodeAnalyzer {
case opc_putstatic:
case opc_putfield: {
FieldIdentifier fi = (FieldIdentifier) canonizeReference(instr);
int size = (opcode == opc_putstatic) ? 0 : 1;
Reference ref = (Reference) instr.objData;
FieldIdentifier fi = (FieldIdentifier)
Main.getClassBundle().getIdentifier(ref);
if (fi != null && !fi.isNotConstant()) {
fi.setNotConstant();
fieldNotConstant(fi);
@ -1150,10 +1192,9 @@ public class ConstantAnalyzer implements Opcodes, CodeAnalyzer {
case opc_getstatic:
case opc_getfield: {
int size = (opcode == opc_getstatic) ? 0 : 1;
FieldIdentifier fi = (FieldIdentifier) canonizeReference(instr);
Reference ref = (Reference) instr.objData;
Type type = Type.tType(ref.getType());
FieldIdentifier fi = (FieldIdentifier)
Main.getClassBundle().getIdentifier(ref);
if (fi != null) {
if (fi.isNotConstant()) {
fi.setReachable();
@ -1168,7 +1209,7 @@ public class ConstantAnalyzer implements Opcodes, CodeAnalyzer {
shortInfo.constant = obj;
result = new ConstValue(obj);
result.addConstantListener(shortInfo);
fi.addFieldListener(m);
fi.addFieldListener(listener);
}
} else
result = unknownValue[type.stackSize()-1];
@ -1179,6 +1220,7 @@ public class ConstantAnalyzer implements Opcodes, CodeAnalyzer {
case opc_invokestatic:
case opc_invokeinterface:
case opc_invokevirtual: {
canonizeReference(instr);
Reference ref = (Reference) instr.objData;
MethodType mt = (MethodType) Type.tType(ref.getType());
boolean constant = true;
@ -1243,8 +1285,7 @@ public class ConstantAnalyzer implements Opcodes, CodeAnalyzer {
if (!constant) {
handleReference(ref, opcode == opc_invokevirtual
|| opcode == opc_invokeinterface);
returnVal =
unknownValue[mt.getReturnType().stackSize()-1];
returnVal = unknownValue[mt.getReturnType().stackSize()-1];
} else {
ConstantInfo shortInfo = new ConstantInfo();
constInfos.put(instr, shortInfo);
@ -1329,13 +1370,15 @@ public class ConstantAnalyzer implements Opcodes, CodeAnalyzer {
}
}
public void analyzeCode() {
public void analyzeCode(MethodIdentifier listener, BytecodeInfo bytecode) {
this.bytecode = bytecode;
working = true;
if (constInfos == null)
constInfos = new HashMap();
Set modifiedQueue = new HashSet();
MethodInfo minfo = bytecode.getMethodInfo();
StackLocalInfo firstInfo = new StackLocalInfo
(bytecode.getMaxLocals(), m.info.isStatic(), m.info.getType(),
(bytecode.getMaxLocals(), minfo.isStatic(), minfo.getType(),
modifiedQueue);
firstInfo.instr = bytecode.getFirstInstr();
firstInfo.instr.tmpInfo = firstInfo;
@ -1447,11 +1490,7 @@ public class ConstantAnalyzer implements Opcodes, CodeAnalyzer {
dest.addPredecessor(second);
}
public BytecodeInfo stripCode() {
if (constInfos == null)
analyzeCode();
// bytecode.dumpCode(GlobalOptions.err);
public void transformCode(BytecodeInfo bytecode) {
for (Instruction instr = bytecode.getFirstInstr();
instr != null; instr = instr.nextByAddr) {
ConstantInfo info = (ConstantInfo) constInfos.get(instr);
@ -1469,7 +1508,7 @@ public class ConstantAnalyzer implements Opcodes, CodeAnalyzer {
instr.objData = info.constant;
if (GlobalOptions.verboseLevel > 2)
GlobalOptions.err.println
(m + ": Replacing " + instr
(bytecode + ": Replacing " + instr
+ " with constant " + info.constant);
}
} else if ((info.flags & CONSTANTFLOW) != 0) {
@ -1481,7 +1520,8 @@ public class ConstantAnalyzer implements Opcodes, CodeAnalyzer {
instr.opcode = opc_pop;
if (GlobalOptions.verboseLevel > 2)
GlobalOptions.err.println
(m + ": Replacing " + instr + " with goto " + pc.addr);
(bytecode + ": Replacing " + instr
+ " with goto " + pc.addr);
instr.alwaysJumps = false;
for (int i = 0; i< instr.succs.length; i++)
instr.succs[i].removePredecessor(instr);
@ -1559,6 +1599,5 @@ public class ConstantAnalyzer implements Opcodes, CodeAnalyzer {
}
}
}
return bytecode;
}
}

Loading…
Cancel
Save