Skip to content

Commit

Permalink
Fix typings
Browse files Browse the repository at this point in the history
  • Loading branch information
MarcMil committed Oct 21, 2024
1 parent 4bae98c commit a5b2ed4
Show file tree
Hide file tree
Showing 11 changed files with 344 additions and 79 deletions.
139 changes: 120 additions & 19 deletions src/main/java/soot/dexpler/DexBody.java
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@
import soot.Body;
import soot.BooleanConstant;
import soot.BooleanType;
import soot.ByteType;
import soot.DoubleType;
import soot.FloatType;
import soot.IntType;
Expand All @@ -81,8 +82,10 @@
import soot.PackManager;
import soot.PhaseOptions;
import soot.PrimType;
import soot.RefLikeType;
import soot.RefType;
import soot.Scene;
import soot.ShortType;
import soot.SootClass;
import soot.SootMethod;
import soot.Trap;
Expand All @@ -99,13 +102,17 @@
import soot.dexpler.instructions.OdexInstruction;
import soot.dexpler.instructions.PseudoInstruction;
import soot.dexpler.instructions.RetypeableInstruction;
import soot.dexpler.tags.ByteOpTag;
import soot.dexpler.tags.DexplerTag;
import soot.dexpler.tags.DoubleOpTag;
import soot.dexpler.tags.FloatOpTag;
import soot.dexpler.tags.IntOpTag;
import soot.dexpler.tags.IntOrFloatOpTag;
import soot.dexpler.tags.LongOrDoubleOpTag;
import soot.dexpler.tags.ShortOpTag;
import soot.dexpler.typing.DalvikTyper;
import soot.jimple.AddExpr;
import soot.jimple.AndExpr;
import soot.jimple.ArrayRef;
import soot.jimple.AssignStmt;
import soot.jimple.BinopExpr;
Expand All @@ -128,9 +135,14 @@
import soot.jimple.NeExpr;
import soot.jimple.NullConstant;
import soot.jimple.NumericConstant;
import soot.jimple.OrExpr;
import soot.jimple.RemExpr;
import soot.jimple.ShlExpr;
import soot.jimple.ShrExpr;
import soot.jimple.Stmt;
import soot.jimple.SubExpr;
import soot.jimple.UshrExpr;
import soot.jimple.XorExpr;
import soot.jimple.internal.JIdentityStmt;
import soot.jimple.toolkits.base.Aggregator;
import soot.jimple.toolkits.scalar.ConditionalBranchFolder;
Expand All @@ -146,7 +158,10 @@
import soot.jimple.toolkits.scalar.UnreachableCodeEliminator;
import soot.jimple.toolkits.typing.fast.BottomType;
import soot.jimple.toolkits.typing.fast.DefaultTypingStrategy;
import soot.jimple.toolkits.typing.fast.IHierarchy;
import soot.jimple.toolkits.typing.fast.ITypingStrategy;
import soot.jimple.toolkits.typing.fast.Integer1Type;
import soot.jimple.toolkits.typing.fast.NeedCastResult;
import soot.jimple.toolkits.typing.fast.TypePromotionUseVisitor;
import soot.options.JBOptions;
import soot.options.Options;
Expand Down Expand Up @@ -723,12 +738,10 @@ public Body jimplify(Body b, SootMethod m) {

// Make sure that we don't have any overlapping uses due to returns
DexReturnInliner.v().transform(jBody);
handleKnownDexTypes(b, jimple);

new SharedInitializationLocalSplitter(DalvikThrowAnalysis.v()).transform(jBody);
// split first to find undefined uses
getLocalSplitter().transform(jBody);

getLocalSplitter().transform(jBody);
// Remove dead code and the corresponding locals before assigning types
getUnreachableCodeEliminator().transform(jBody);
DeadAssignmentEliminator.v().transform(jBody);
Expand Down Expand Up @@ -812,6 +825,8 @@ public Body jimplify(Body b, SootMethod m) {
}
DexFillArrayDataTransformer.v().transform(jBody);
// SharedInitializationLocalSplitter destroys the inserted casts, so we have to reintroduce them
getLocalSplitter().transform(jBody);

MultiMap<Local, Type> maybetypeConstraints = new HashMultiMap<>();
handleKnownDexTypes(b, jimple);
handleKnownDexArrayTypes(b, jimple, maybetypeConstraints);
Expand All @@ -823,10 +838,7 @@ public Body jimplify(Body b, SootMethod m) {
}
}

getLocalSplitter().transform(jBody);

new soot.jimple.toolkits.typing.fast.TypeResolver(jBody) {

protected soot.jimple.toolkits.typing.fast.TypePromotionUseVisitor createTypePromotionUseVisitor(JimpleBody jb,
soot.jimple.toolkits.typing.fast.Typing tg) {
return new TypePromotionUseVisitor(jb, tg) {
Expand All @@ -846,12 +858,15 @@ protected boolean allowConversion(Type ancestor, Type child) {
}

public Type promote(Type tlow, Type thigh) {
if (thigh instanceof BooleanType) {
if (tlow instanceof IntegerType) {
//Well... in Android's dex code, 0 = false and everything else is true
//While the compiler should never generate such code, there can be found code like this in the wild.
//And Android accepts it!
//Thus, we allow the type promotion and then correct the boolean constants
if (thigh instanceof BooleanType && tlow instanceof IntegerType) {
//Well... in Android's dex code, 0 = false and everything else is true
//While the compiler should never generate such code, there can be found code like this in the wild.
//And Android accepts it!
//Thus, we allow the type promotion and then correct the boolean constants
return thigh;
}
if (tlow instanceof IntegerType) {
if (thigh instanceof FloatType || thigh instanceof IntType) {
return thigh;
}
}
Expand All @@ -862,6 +877,24 @@ public Type promote(Type tlow, Type thigh) {

}

protected soot.jimple.toolkits.typing.fast.BytecodeHierarchy createBytecodeHierarchy() {
return new soot.jimple.toolkits.typing.fast.BytecodeHierarchy() {
public java.util.Collection<Type> lcas(Type a, Type b, boolean useWeakObjectType) {
Collection<Type> s = super.lcas(a, b, useWeakObjectType);
if (s.isEmpty()) {
//when we merge a null constant and anything non-primitive, we use the non-primitive type
if (a instanceof Integer1Type && b instanceof RefLikeType) {
return Collections.singleton(b);
}
if (b instanceof Integer1Type && a instanceof RefLikeType) {
return Collections.singleton(a);
}
}
return s;
}
};
}

@Override
protected Collection<Type> reduceToAllowedTypesForLocal(Collection<Type> lcas, Local v) {
Collection<Type> t = definiteConstraints.get(v);
Expand Down Expand Up @@ -892,6 +925,49 @@ protected soot.jimple.toolkits.typing.fast.ITypingStrategy getTypingStrategy() {
protected CastInsertionUseVisitor createCastInsertionUseVisitor(soot.jimple.toolkits.typing.fast.Typing tg,
soot.jimple.toolkits.typing.fast.IHierarchy h, boolean countOnly) {
return new CastInsertionUseVisitor(countOnly, jBody, tg, h) {

protected NeedCastResult needCast(Type target, Type from, IHierarchy h) {
NeedCastResult r = super.needCast(target, from, h);
if (r == NeedCastResult.NEEDS_CAST) {
if (target instanceof IntType || target instanceof FloatType) {
if (from instanceof IntegerType || from instanceof FloatType) {
return NeedCastResult.DISCOURAGED_TARGET_TYPE;
}
}
if (target instanceof LongType || target instanceof DoubleType) {
if (from instanceof IntegerType || from instanceof LongType || from instanceof DoubleType) {
return NeedCastResult.DISCOURAGED_TARGET_TYPE;
}
}
return r;
}

//we need to this since some types are final already. Otherwise,
//we get no casts at all.
if (target instanceof PrimType && from instanceof PrimType) {
if (!from.isAllowedInFinalCode()) {
from = from.getDefaultFinalType();
}
if (target.isAllowedInFinalCode()) {
if (target == from) {
return NeedCastResult.DOESNT_NEED_CAST;
}
if (target instanceof IntType || target instanceof FloatType) {
if (from instanceof IntegerType || from instanceof FloatType) {
return NeedCastResult.DISCOURAGED_TARGET_TYPE;
}
}
if (target instanceof LongType || target instanceof DoubleType) {
if (from instanceof IntegerType || from instanceof LongType || from instanceof DoubleType) {
return NeedCastResult.DISCOURAGED_TARGET_TYPE;
}
}
return NeedCastResult.NEEDS_CAST;
}
}
return NeedCastResult.DOESNT_NEED_CAST;
}

@Override
public Value visit(Value op, Type useType, Stmt stmt, boolean checkOnly) {
if (op instanceof LongConstant && useType instanceof DoubleType) {
Expand Down Expand Up @@ -1008,7 +1084,6 @@ public Value visit(Value op, Type useType, Stmt stmt, boolean checkOnly) {
// again lead to unused locals which we have to remove.
LocalPacker.v().transform(jBody);
UnusedLocalEliminator.v().transform(jBody);
PackManager.v().getTransform("jb.lns").apply(jBody);

// Some apps reference static fields as instance fields. We fix this
// on the fly.
Expand Down Expand Up @@ -1240,19 +1315,29 @@ private void handleKnownDexTypes(Body b, final Jimple jimple) {
if (rop instanceof BinopExpr) {
boolean isDouble = u.hasTag(DoubleOpTag.NAME);
boolean isFloat = u.hasTag(FloatOpTag.NAME);
boolean isInt = u.hasTag(IntOpTag.NAME);
boolean isShort = u.hasTag(ShortOpTag.NAME);
boolean isByte = u.hasTag(ByteOpTag.NAME);
if (rop instanceof AddExpr || rop instanceof SubExpr || rop instanceof MulExpr || rop instanceof DivExpr
|| rop instanceof RemExpr) {
|| rop instanceof RemExpr || rop instanceof XorExpr || rop instanceof UshrExpr || rop instanceof ShrExpr
|| rop instanceof ShlExpr || rop instanceof AndExpr || rop instanceof OrExpr) {
Type t = null;
if (isDouble) {
t = DoubleType.v();
} else if (isFloat) {
t = FloatType.v();
} else if (isInt) {
t = IntType.v();
} else if (isShort) {
t = ShortType.v();
} else if (isByte) {
t = ByteType.v();
}
if (t != null) {
Local l = createOrGetVariableOfType(b, convSingle, t);
Value prev = def.getLeftOp();
def.setLeftOp(l);
units.insertAfter(jimple.newAssignStmt(prev, jimple.newCastExpr(l, t)), u);
units.insertAfter(jimple.newAssignStmt(prev, l), u);
}
}
BinopExpr bop = (BinopExpr) rop;
Expand All @@ -1276,8 +1361,7 @@ private void handleKnownDexTypes(Body b, final Jimple jimple) {
convDouble[idxConvVar] = jimple.newLocal(freshLocalName("lclConvToDouble" + idxConvVar), DoubleType.v());
b.getLocals().add(convDouble[idxConvVar]);
}
units.insertBefore(
jimple.newAssignStmt(convDouble[idxConvVar], jimple.newCastExpr(cmp.getValue(), DoubleType.v())), u);
units.insertBefore(jimple.newAssignStmt(convDouble[idxConvVar], cmp.getValue()), u);
cmp.setValue(convDouble[idxConvVar]);
idxConvVar++;
}
Expand All @@ -1287,8 +1371,7 @@ private void handleKnownDexTypes(Body b, final Jimple jimple) {
convFloat[idxConvVar] = jimple.newLocal(freshLocalName("lclConvToFloat" + idxConvVar), FloatType.v());
b.getLocals().add(convFloat[idxConvVar]);
}
units.insertBefore(
jimple.newAssignStmt(convFloat[idxConvVar], jimple.newCastExpr(cmp.getValue(), FloatType.v())), u);
units.insertBefore(jimple.newAssignStmt(convFloat[idxConvVar], cmp.getValue()), u);
cmp.setValue(convFloat[idxConvVar]);
idxConvVar++;
}
Expand All @@ -1298,6 +1381,24 @@ private void handleKnownDexTypes(Body b, final Jimple jimple) {
}

}
Stmt s = (Stmt) u;
if (s.containsInvokeExpr()) {
InvokeExpr inv = s.getInvokeExpr();
for (int pidx = 0; pidx < inv.getArgCount(); pidx++) {
Value arg = inv.getArg(pidx);
if (arg instanceof Constant) {
Type t = inv.getMethodRef().getParameterType(pidx);
if (t instanceof DoubleType && arg instanceof LongConstant) {
long vVal = ((LongConstant) arg).value;
inv.setArg(pidx, DoubleConstant.v(Double.longBitsToDouble(vVal)));
}
if (t instanceof FloatType && arg instanceof IntConstant) {
int vVal = ((IntConstant) arg).value;
inv.setArg(pidx, FloatConstant.v(Float.intBitsToFloat(vVal)));
}
}
}
}
u = units.getSuccOf(u);
}
for (Unit u1 : units) {
Expand Down
7 changes: 7 additions & 0 deletions src/main/java/soot/jimple/internal/JEqExpr.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package soot.jimple.internal;

import soot.BooleanType;

/*-
* #%L
* Soot - a J*va Optimization Framework
Expand Down Expand Up @@ -46,6 +48,11 @@ public void apply(Switch sw) {
((ExprSwitch) sw).caseEqExpr(this);
}

@Override
public Type getType() {
return BooleanType.v();
}

@Override
protected Unit makeBafInst(Type opType) {
throw new RuntimeException("unsupported conversion: " + this);
Expand Down
7 changes: 7 additions & 0 deletions src/main/java/soot/jimple/internal/JGeExpr.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package soot.jimple.internal;

import soot.BooleanType;

/*-
* #%L
* Soot - a J*va Optimization Framework
Expand Down Expand Up @@ -41,6 +43,11 @@ public final String getSymbol() {
return " >= ";
}

@Override
public Type getType() {
return BooleanType.v();
}

@Override
public void apply(Switch sw) {
((ExprSwitch) sw).caseGeExpr(this);
Expand Down
7 changes: 7 additions & 0 deletions src/main/java/soot/jimple/internal/JGtExpr.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package soot.jimple.internal;

import soot.BooleanType;

/*-
* #%L
* Soot - a J*va Optimization Framework
Expand Down Expand Up @@ -41,6 +43,11 @@ public final String getSymbol() {
return " > ";
}

@Override
public Type getType() {
return BooleanType.v();
}

@Override
public void apply(Switch sw) {
((ExprSwitch) sw).caseGtExpr(this);
Expand Down
7 changes: 7 additions & 0 deletions src/main/java/soot/jimple/internal/JLeExpr.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package soot.jimple.internal;

import soot.BooleanType;

/*-
* #%L
* Soot - a J*va Optimization Framework
Expand Down Expand Up @@ -41,6 +43,11 @@ public final String getSymbol() {
return " <= ";
}

@Override
public Type getType() {
return BooleanType.v();
}

@Override
public void apply(Switch sw) {
((ExprSwitch) sw).caseLeExpr(this);
Expand Down
7 changes: 7 additions & 0 deletions src/main/java/soot/jimple/internal/JLtExpr.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package soot.jimple.internal;

import soot.BooleanType;

/*-
* #%L
* Soot - a J*va Optimization Framework
Expand Down Expand Up @@ -41,6 +43,11 @@ public final String getSymbol() {
return " < ";
}

@Override
public Type getType() {
return BooleanType.v();
}

@Override
public void apply(Switch sw) {
((ExprSwitch) sw).caseLtExpr(this);
Expand Down
7 changes: 7 additions & 0 deletions src/main/java/soot/jimple/internal/JNeExpr.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package soot.jimple.internal;

import soot.BooleanType;

/*-
* #%L
* Soot - a J*va Optimization Framework
Expand Down Expand Up @@ -41,6 +43,11 @@ public final String getSymbol() {
return " != ";
}

@Override
public Type getType() {
return BooleanType.v();
}

@Override
public void apply(Switch sw) {
((ExprSwitch) sw).caseNeExpr(this);
Expand Down
Loading

0 comments on commit a5b2ed4

Please sign in to comment.