Skip to content

Commit

Permalink
Support for .NET checked instructions
Browse files Browse the repository at this point in the history
  • Loading branch information
MarcMil committed Aug 12, 2024
1 parent 2814cc4 commit f97a13c
Show file tree
Hide file tree
Showing 24 changed files with 562 additions and 166 deletions.
217 changes: 145 additions & 72 deletions src/main/generated/protobuf/soot/dotnet/proto/ProtoIlInstructions.java

Large diffs are not rendered by default.

83 changes: 44 additions & 39 deletions src/main/java/soot/ByteConstant.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,43 +3,48 @@
import soot.jimple.IntConstant;

public class ByteConstant extends IntConstant {
private static final long serialVersionUID = 0L;
public static final ByteConstant ZERO = new ByteConstant(0);
public static final ByteConstant ONE = new ByteConstant(1);

private static final int MAX_CACHE = 128;
private static final int MIN_CACHE = -127;
private static final int ABS_MIN_CACHE = Math.abs(MIN_CACHE);
private static final ByteConstant[] CACHED = new ByteConstant[1 + MAX_CACHE + ABS_MIN_CACHE];

public ByteConstant(byte value) {
super(value);
}

public ByteConstant(int value) {
super((byte) value);
}

public static ByteConstant v(int value) {
if (value >= MIN_CACHE && value <= MAX_CACHE) {
int idx = value + ABS_MIN_CACHE;
ByteConstant c = CACHED[idx];
if (c != null) {
return c;
}
c = new ByteConstant(value);
CACHED[idx] = c;
return c;
}
return new ByteConstant(value);
}

public byte getByte() {
return (byte) value;
}

@Override
public Type getType() {
return ByteType.v();
}
private static final long serialVersionUID = 0L;
public static final ByteConstant ZERO = new ByteConstant(0);
public static final ByteConstant ONE = new ByteConstant(1);

private static final int MAX_CACHE = 128;
private static final int MIN_CACHE = -127;
private static final int ABS_MIN_CACHE = Math.abs(MIN_CACHE);
private static final ByteConstant[] CACHED = new ByteConstant[1 + MAX_CACHE + ABS_MIN_CACHE];

public ByteConstant(byte value) {
super(value);
}

public ByteConstant(int value) {
super((byte) value);
}

public static ByteConstant v(int value) {
if (value >= MIN_CACHE && value <= MAX_CACHE) {
int idx = value + ABS_MIN_CACHE;
ByteConstant c = CACHED[idx];
if (c != null) {
return c;
}
c = new ByteConstant(value);
CACHED[idx] = c;
return c;
}
return new ByteConstant(value);
}

public byte getByte() {
return (byte) value;
}

@Override
public Number getNumericValue() {
return (byte) value;
}

@Override
public Type getType() {
return ByteType.v();
}
}
74 changes: 37 additions & 37 deletions src/main/java/soot/CharConstant.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,41 +3,41 @@
import soot.jimple.IntConstant;

public class CharConstant extends IntConstant {
private static final long serialVersionUID = 0L;

private static final int MAX_CACHE = 128;
private static final int MIN_CACHE = -127;
private static final int ABS_MIN_CACHE = Math.abs(MIN_CACHE);
private static final CharConstant[] CACHED = new CharConstant[1 + MAX_CACHE + ABS_MIN_CACHE];

public CharConstant(char value) {
super(value);
}

public CharConstant(int value) {
super((char) value);
}

public static CharConstant v(int value) {
if (value >= MIN_CACHE && value <= MAX_CACHE) {
int idx = value + ABS_MIN_CACHE;
CharConstant c = CACHED[idx];
if (c != null) {
return c;
}
c = new CharConstant(value);
CACHED[idx] = c;
return c;
}
return new CharConstant(value);
}

public char getChar() {
return (char) value;
}

@Override
public Type getType() {
return CharType.v();
}
private static final long serialVersionUID = 0L;

private static final int MAX_CACHE = 128;
private static final int MIN_CACHE = -127;
private static final int ABS_MIN_CACHE = Math.abs(MIN_CACHE);
private static final CharConstant[] CACHED = new CharConstant[1 + MAX_CACHE + ABS_MIN_CACHE];

public CharConstant(char value) {
super(value);
}

public CharConstant(int value) {
super((char) value);
}

public static CharConstant v(int value) {
if (value >= MIN_CACHE && value <= MAX_CACHE) {
int idx = value + ABS_MIN_CACHE;
CharConstant c = CACHED[idx];
if (c != null) {
return c;
}
c = new CharConstant(value);
CACHED[idx] = c;
return c;
}
return new CharConstant(value);
}

public char getChar() {
return (char) value;
}

@Override
public Type getType() {
return CharType.v();
}
}
5 changes: 5 additions & 0 deletions src/main/java/soot/DecimalConstant.java
Original file line number Diff line number Diff line change
Expand Up @@ -143,4 +143,9 @@ public IntConstant cmpl(RealConstant constant) {
public NumericConstant negate() {
return DecimalConstant.v(this.value.negate());
}

@Override
public Number getNumericValue() {
return value;
}
}
2 changes: 2 additions & 0 deletions src/main/java/soot/UByteType.java
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@
public class UByteType extends PrimType implements DotNetINumber {

public static final int HASHCODE = 0x213D1329;
public static final int MIN_VALUE = 0;
public static final int MAX_VALUE = 255;

public UByteType(Singletons.Global g) {
}
Expand Down
2 changes: 2 additions & 0 deletions src/main/java/soot/UIntType.java
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@
public class UIntType extends PrimType implements DotNetINumber {

public static final int HASHCODE = 0xB347239F;
public static final long MAX_VALUE = 4294967295L;
public static final int MIN_VALUE = 0;

public UIntType(Singletons.Global g) {
}
Expand Down
4 changes: 3 additions & 1 deletion src/main/java/soot/UShortType.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,14 @@
import soot.util.Switch;

/**
* Soot representation of the .NET built-in type 'short'. Implemented as a singleton.
* Soot representation of the .NET built-in type 'ushort'. Implemented as a singleton.
*/
@SuppressWarnings("serial")
public class UShortType extends PrimType implements DotNetINumber {

public static final int HASHCODE = 0x5B817DD3;
public static final int MAX_VALUE = 65535;
public static final int MIN_VALUE = 0;

public UShortType(Singletons.Global g) {
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,10 @@
import soot.jimple.TableSwitchStmt;
import soot.jimple.ThrowStmt;
import soot.jimple.VirtualInvokeExpr;
import soot.jimple.internal.JCheckedAddExpr;
import soot.jimple.internal.JCheckedCastExpr;
import soot.jimple.internal.JCheckedMulExpr;
import soot.jimple.internal.JCheckedSubExpr;
import soot.toolkits.exceptions.ThrowableSet;
import soot.toolkits.exceptions.UnitThrowAnalysis;

Expand Down Expand Up @@ -426,6 +430,26 @@ public void defaultCase(Object obj) {
protected ValueSwitch valueSwitch() {
return new UnitThrowAnalysis.ValueSwitch() {

@Override
public void caseCheckedAddExpr(JCheckedAddExpr v) {
result = result.add(Scene.v().getRefType(DotnetBasicTypes.SYSTEM_OVERFLOWEXCEPTION));
}

@Override
public void caseCheckedMulExpr(JCheckedMulExpr v) {
result = result.add(Scene.v().getRefType(DotnetBasicTypes.SYSTEM_OVERFLOWEXCEPTION));
}

@Override
public void caseCheckedSubExpr(JCheckedSubExpr v) {
result = result.add(Scene.v().getRefType(DotnetBasicTypes.SYSTEM_OVERFLOWEXCEPTION));
}

@Override
public void caseCheckedCastExpr(JCheckedCastExpr v) {
result = result.add(Scene.v().getRefType(DotnetBasicTypes.SYSTEM_OVERFLOWEXCEPTION));
}

@Override
public void caseClassConstant(ClassConstant c) {
result = result.add(Scene.v().getRefType(DotnetBasicTypes.SYSTEM_TYPELOADEXCEPTION));
Expand Down Expand Up @@ -506,8 +530,7 @@ public void caseInstanceOfExpr(InstanceOfExpr expr) {
public void caseNewArrayExpr(NewArrayExpr expr) {
result = result.add(Scene.v().getRefType(DotnetBasicTypes.SYSTEM_OUTOFMEMORYEXCEPTION));
Value count = expr.getSize();
if (!(count instanceof IntConstant)
|| ((IntConstant) count).lessThan(INT_CONSTANT_ZERO).equals(INT_CONSTANT_ZERO)) {
if (!(count instanceof IntConstant) || ((IntConstant) count).lessThan(INT_CONSTANT_ZERO).equals(INT_CONSTANT_ZERO)) {
result = result.add(Scene.v().getRefType(DotnetBasicTypes.SYSTEM_OVERFLOWEXCEPTION));
}
result = result.add(mightThrow(count));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,30 +75,43 @@ public Value jimplifyExpr(Body jb) {
Value right = CilInstructionFactory.fromInstructionMsg(instruction.getRight(), dotnetBody, cilBlock).jimplifyExpr(jb);
right = inlineCastExpr(right);
right = simplifyComplexExpression(jb, right);
Jimple jimple = Jimple.v();
switch (instruction.getOperator()) {
case Add:
return Jimple.v().newAddExpr(left, right);
if (instruction.getCheckForOverflow()) {
return jimple.newCheckedAddExpr(left, right);
} else {
return jimple.newAddExpr(left, right);
}
case Sub:
return Jimple.v().newSubExpr(left, right);
if (instruction.getCheckForOverflow()) {
return jimple.newCheckedSubExpr(left, right);
} else {
return jimple.newSubExpr(left, right);
}
case Mul:
return Jimple.v().newMulExpr(left, right);
if (instruction.getCheckForOverflow()) {
return jimple.newCheckedMulExpr(left, right);
} else {
return jimple.newMulExpr(left, right);
}
case Div:
return Jimple.v().newDivExpr(left, right);
return jimple.newDivExpr(left, right);
case Rem:
return Jimple.v().newRemExpr(left, right);
return jimple.newRemExpr(left, right);
case BitAnd:
return Jimple.v().newAndExpr(left, right);
return jimple.newAndExpr(left, right);
case BitOr:
return Jimple.v().newOrExpr(left, right);
return jimple.newOrExpr(left, right);
case BitXor:
return Jimple.v().newXorExpr(left, right);
return jimple.newXorExpr(left, right);
case ShiftLeft:
return Jimple.v().newShlExpr(left, right);
return jimple.newShlExpr(left, right);
case ShiftRight:
if (instruction.getSign().equals(ProtoIlInstructions.IlInstructionMsg.IlSign.Signed)) {
return Jimple.v().newShrExpr(left, right);
return jimple.newShrExpr(left, right);
}
return Jimple.v().newUshrExpr(left, right);
return jimple.newUshrExpr(left, right);
default:
return null;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,10 @@ public Value jimplifyExpr(Body jb) {
}
argument = simplifyComplexExpression(jb, argument);

return Jimple.v().newCastExpr(argument, convType);
if (instruction.getCheckForOverflow()) {
return Jimple.v().newCheckedCastExpr(argument, convType);
} else {
return Jimple.v().newCastExpr(argument, convType);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ public class DelegateHandler {
private static final String INSTANCE_FIELDNAME = "instance";
private static final String GET_LIST = "getList";

public static final String REMOVE_METHOD_NAME = "remove";
public static final String REMOVE_METHOD_NAME = "removeDelegate";
public static final String COMBINE_WITH_METHOD_NAME = "combineWith";
public static final String INVOKE_METHOD_NAME = "doInvoke";
public static final String DELEGATE_LIST_NAME = "DelegateList";
Expand Down
2 changes: 0 additions & 2 deletions src/main/java/soot/dotnet/members/method/DotnetBody.java
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@
import soot.Value;
import soot.ValueBox;
import soot.VoidType;
import soot.dexpler.TrapMinimizer;
import soot.dotnet.instructions.CilBlockContainer;
import soot.dotnet.members.ByReferenceWrapperGenerator;
import soot.dotnet.members.DotnetMethod;
Expand Down Expand Up @@ -157,7 +156,6 @@ public void jimplify(JimpleBody jb) {
// PackManager.v().getTransform("jb.lns").apply(jb);

TrapTightener.v().transform(jb);
TrapMinimizer.v().transform(jb);
Aggregator.v().transform(jb);

ConditionalBranchFolder.v().transform(jb);
Expand Down
5 changes: 5 additions & 0 deletions src/main/java/soot/jimple/DoubleConstant.java
Original file line number Diff line number Diff line change
Expand Up @@ -206,4 +206,9 @@ private void assertInstanceOf(NumericConstant constant) {
throw new IllegalArgumentException("DoubleConstant expected");
}
}

@Override
public Number getNumericValue() {
return value;
}
}
22 changes: 22 additions & 0 deletions src/main/java/soot/jimple/ExprSwitch.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
package soot.jimple;

import soot.jimple.internal.JCheckedAddExpr;
import soot.jimple.internal.JCheckedCastExpr;
import soot.jimple.internal.JCheckedMulExpr;
import soot.jimple.internal.JCheckedSubExpr;

/*-
* #%L
* Soot - a J*va Optimization Framework
Expand Down Expand Up @@ -88,4 +93,21 @@ public interface ExprSwitch extends soot.util.Switch {
public abstract void caseNegExpr(NegExpr v);

public abstract void defaultCase(Object obj);

public default void caseCheckedAddExpr(JCheckedAddExpr v) {
caseAddExpr(v);
}

public default void caseCheckedSubExpr(JCheckedSubExpr v) {
caseSubExpr(v);
}

public default void caseCheckedMulExpr(JCheckedMulExpr v) {
caseMulExpr(v);
}

public default void caseCheckedCastExpr(JCheckedCastExpr v) {
caseCastExpr(v);
}

}
Loading

0 comments on commit f97a13c

Please sign in to comment.