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 { public class ConstantAnalyzer implements Opcodes, CodeAnalyzer {
boolean working; boolean working;
MethodIdentifier m;
BytecodeInfo bytecode;
Map constInfos; Map constInfos;
BytecodeInfo bytecode;
Identifier listener;
private static ConstantRuntimeEnvironment runtime private static ConstantRuntimeEnvironment runtime
= new ConstantRuntimeEnvironment(); = new ConstantRuntimeEnvironment();
@ -410,9 +411,7 @@ public class ConstantAnalyzer implements Opcodes, CodeAnalyzer {
private static ConstantInfo unknownConstInfo = new ConstantInfo(); private static ConstantInfo unknownConstInfo = new ConstantInfo();
public ConstantAnalyzer(BytecodeInfo code, MethodIdentifier method) { public ConstantAnalyzer() {
this.bytecode = code;
this.m = method;
} }
public void mergeInfo(Instruction instr, public void mergeInfo(Instruction instr,
@ -425,6 +424,50 @@ public class ConstantAnalyzer implements Opcodes, CodeAnalyzer {
((StackLocalInfo)instr.tmpInfo).merge(info); ((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) { public void handleReference(Reference ref, boolean isVirtual) {
String clName = ref.getClazz(); String clName = ref.getClazz();
/* Don't have to reach array methods */ /* Don't have to reach array methods */
@ -1135,10 +1178,9 @@ public class ConstantAnalyzer implements Opcodes, CodeAnalyzer {
case opc_putstatic: case opc_putstatic:
case opc_putfield: { case opc_putfield: {
FieldIdentifier fi = (FieldIdentifier) canonizeReference(instr);
int size = (opcode == opc_putstatic) ? 0 : 1; int size = (opcode == opc_putstatic) ? 0 : 1;
Reference ref = (Reference) instr.objData; Reference ref = (Reference) instr.objData;
FieldIdentifier fi = (FieldIdentifier)
Main.getClassBundle().getIdentifier(ref);
if (fi != null && !fi.isNotConstant()) { if (fi != null && !fi.isNotConstant()) {
fi.setNotConstant(); fi.setNotConstant();
fieldNotConstant(fi); fieldNotConstant(fi);
@ -1150,10 +1192,9 @@ public class ConstantAnalyzer implements Opcodes, CodeAnalyzer {
case opc_getstatic: case opc_getstatic:
case opc_getfield: { case opc_getfield: {
int size = (opcode == opc_getstatic) ? 0 : 1; int size = (opcode == opc_getstatic) ? 0 : 1;
FieldIdentifier fi = (FieldIdentifier) canonizeReference(instr);
Reference ref = (Reference) instr.objData; Reference ref = (Reference) instr.objData;
Type type = Type.tType(ref.getType()); Type type = Type.tType(ref.getType());
FieldIdentifier fi = (FieldIdentifier)
Main.getClassBundle().getIdentifier(ref);
if (fi != null) { if (fi != null) {
if (fi.isNotConstant()) { if (fi.isNotConstant()) {
fi.setReachable(); fi.setReachable();
@ -1168,7 +1209,7 @@ public class ConstantAnalyzer implements Opcodes, CodeAnalyzer {
shortInfo.constant = obj; shortInfo.constant = obj;
result = new ConstValue(obj); result = new ConstValue(obj);
result.addConstantListener(shortInfo); result.addConstantListener(shortInfo);
fi.addFieldListener(m); fi.addFieldListener(listener);
} }
} else } else
result = unknownValue[type.stackSize()-1]; result = unknownValue[type.stackSize()-1];
@ -1179,6 +1220,7 @@ public class ConstantAnalyzer implements Opcodes, CodeAnalyzer {
case opc_invokestatic: case opc_invokestatic:
case opc_invokeinterface: case opc_invokeinterface:
case opc_invokevirtual: { case opc_invokevirtual: {
canonizeReference(instr);
Reference ref = (Reference) instr.objData; Reference ref = (Reference) instr.objData;
MethodType mt = (MethodType) Type.tType(ref.getType()); MethodType mt = (MethodType) Type.tType(ref.getType());
boolean constant = true; boolean constant = true;
@ -1243,8 +1285,7 @@ public class ConstantAnalyzer implements Opcodes, CodeAnalyzer {
if (!constant) { if (!constant) {
handleReference(ref, opcode == opc_invokevirtual handleReference(ref, opcode == opc_invokevirtual
|| opcode == opc_invokeinterface); || opcode == opc_invokeinterface);
returnVal = returnVal = unknownValue[mt.getReturnType().stackSize()-1];
unknownValue[mt.getReturnType().stackSize()-1];
} else { } else {
ConstantInfo shortInfo = new ConstantInfo(); ConstantInfo shortInfo = new ConstantInfo();
constInfos.put(instr, shortInfo); 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; working = true;
if (constInfos == null) if (constInfos == null)
constInfos = new HashMap(); constInfos = new HashMap();
Set modifiedQueue = new HashSet(); Set modifiedQueue = new HashSet();
MethodInfo minfo = bytecode.getMethodInfo();
StackLocalInfo firstInfo = new StackLocalInfo StackLocalInfo firstInfo = new StackLocalInfo
(bytecode.getMaxLocals(), m.info.isStatic(), m.info.getType(), (bytecode.getMaxLocals(), minfo.isStatic(), minfo.getType(),
modifiedQueue); modifiedQueue);
firstInfo.instr = bytecode.getFirstInstr(); firstInfo.instr = bytecode.getFirstInstr();
firstInfo.instr.tmpInfo = firstInfo; firstInfo.instr.tmpInfo = firstInfo;
@ -1447,11 +1490,7 @@ public class ConstantAnalyzer implements Opcodes, CodeAnalyzer {
dest.addPredecessor(second); dest.addPredecessor(second);
} }
public BytecodeInfo stripCode() { public void transformCode(BytecodeInfo bytecode) {
if (constInfos == null)
analyzeCode();
// bytecode.dumpCode(GlobalOptions.err);
for (Instruction instr = bytecode.getFirstInstr(); for (Instruction instr = bytecode.getFirstInstr();
instr != null; instr = instr.nextByAddr) { instr != null; instr = instr.nextByAddr) {
ConstantInfo info = (ConstantInfo) constInfos.get(instr); ConstantInfo info = (ConstantInfo) constInfos.get(instr);
@ -1469,7 +1508,7 @@ public class ConstantAnalyzer implements Opcodes, CodeAnalyzer {
instr.objData = info.constant; instr.objData = info.constant;
if (GlobalOptions.verboseLevel > 2) if (GlobalOptions.verboseLevel > 2)
GlobalOptions.err.println GlobalOptions.err.println
(m + ": Replacing " + instr (bytecode + ": Replacing " + instr
+ " with constant " + info.constant); + " with constant " + info.constant);
} }
} else if ((info.flags & CONSTANTFLOW) != 0) { } else if ((info.flags & CONSTANTFLOW) != 0) {
@ -1481,7 +1520,8 @@ public class ConstantAnalyzer implements Opcodes, CodeAnalyzer {
instr.opcode = opc_pop; instr.opcode = opc_pop;
if (GlobalOptions.verboseLevel > 2) if (GlobalOptions.verboseLevel > 2)
GlobalOptions.err.println GlobalOptions.err.println
(m + ": Replacing " + instr + " with goto " + pc.addr); (bytecode + ": Replacing " + instr
+ " with goto " + pc.addr);
instr.alwaysJumps = false; instr.alwaysJumps = false;
for (int i = 0; i< instr.succs.length; i++) for (int i = 0; i< instr.succs.length; i++)
instr.succs[i].removePredecessor(instr); instr.succs[i].removePredecessor(instr);
@ -1559,6 +1599,5 @@ public class ConstantAnalyzer implements Opcodes, CodeAnalyzer {
} }
} }
} }
return bytecode;
} }
} }

Loading…
Cancel
Save