use of soot.ArrayType in project soot by Sable.
the class ExceptionChecker method checkInvokeExpr.
protected void checkInvokeExpr(Body b, InvokeExpr ie, Stmt s) {
if (ie instanceof InstanceInvokeExpr && ((InstanceInvokeExpr) ie).getBase().getType() instanceof ArrayType && ie.getMethodRef().name().equals("clone") && ie.getMethodRef().parameterTypes().size() == 0)
// the call is to the clone() method of an array type, which
return;
// is defined not to throw any exceptions; if we left this to
// normal resolution we'd get the method in Object which does
// throw CloneNotSupportedException
List exceptions = ie instanceof InterfaceInvokeExpr ? // the method in supertypes.
getExceptionSpec(ie.getMethodRef().declaringClass(), ie.getMethodRef().getSubSignature()) : // Otherwise, we just do normal resolution.
ie.getMethod().getExceptionsUnsafe();
if (exceptions == null)
return;
Iterator it = exceptions.iterator();
while (it.hasNext()) {
SootClass sc = (SootClass) it.next();
if (isThrowDeclared(b, sc) || isExceptionCaught(b, s, sc.getType()))
continue;
if (reporter != null) {
if (s instanceof InvokeStmt) {
reporter.reportError(new ExceptionCheckerError(b.getMethod(), sc, s, (SourceLnPosTag) s.getTag("SourceLnPosTag")));
} else if (s instanceof AssignStmt) {
reporter.reportError(new ExceptionCheckerError(b.getMethod(), sc, s, (SourceLnPosTag) ((AssignStmt) s).getRightOpBox().getTag("SourceLnPosTag")));
}
}
}
}
use of soot.ArrayType in project soot by Sable.
the class OnFlyCallGraphBuilder method resolveInvoke.
private void resolveInvoke(Collection<InvokeCallSite> list) {
for (InvokeCallSite ics : list) {
Set<Type> s = reachingBaseTypes.get(ics.base());
if (s == null || s.isEmpty()) {
continue;
}
if (ics.reachingTypes() != null) {
assert ics.nullnessCode() != InvokeCallSite.MUST_BE_NULL;
resolveStaticTypes(s, ics);
continue;
}
boolean mustNotBeNull = ics.nullnessCode() == InvokeCallSite.MUST_NOT_BE_NULL;
boolean mustBeNull = ics.nullnessCode() == InvokeCallSite.MUST_BE_NULL;
// yet, then generate nullary methods
if (mustBeNull || (ics.nullnessCode() == InvokeCallSite.MAY_BE_NULL && (!invokeArgsToSize.containsKey(ics.argArray()) || !reachingArgTypes.containsKey(ics.argArray())))) {
for (Type bType : s) {
assert bType instanceof RefType;
SootClass baseClass = ((RefType) bType).getSootClass();
assert !baseClass.isInterface();
Iterator<SootMethod> mIt = getPublicNullaryMethodIterator(baseClass);
while (mIt.hasNext()) {
SootMethod sm = mIt.next();
cm.addVirtualEdge(ics.container(), ics.stmt(), sm, Kind.REFL_INVOKE, null);
}
}
} else {
/*
* In this branch, either the invoke arg must not be null, or may be null and we
* have size and type information. Invert the above condition: ~mustBeNull &&
* (~mayBeNull || (has-size && has-type)) => (~mustBeNull && ~mayBeNull) ||
* (~mustBeNull && has-size && has-type) => mustNotBeNull || (~mustBeNull &&
* has-types && has-size) => mustNotBeNull || (mayBeNull && has-types &&
* has-size)
*/
Set<Type> reachingTypes = reachingArgTypes.get(ics.argArray());
/*
* the path condition allows must-not-be null without type and size info. Do
* nothing in this case. THIS IS UNSOUND if default null values in an argument
* array are used.
*/
if (reachingTypes == null || !invokeArgsToSize.containsKey(ics.argArray())) {
assert ics.nullnessCode() == InvokeCallSite.MUST_NOT_BE_NULL : ics;
return;
}
assert reachingTypes != null && invokeArgsToSize.containsKey(ics.argArray());
BitSet methodSizes = invokeArgsToSize.get(ics.argArray());
for (Type bType : s) {
assert bType instanceof RefLikeType;
// we do not handle static methods or array reflection
if (bType instanceof NullType || bType instanceof ArrayType) {
continue;
} else {
SootClass baseClass = ((RefType) bType).getSootClass();
Iterator<SootMethod> mIt = getPublicMethodIterator(baseClass, reachingTypes, methodSizes, mustNotBeNull);
while (mIt.hasNext()) {
SootMethod sm = mIt.next();
cm.addVirtualEdge(ics.container(), ics.stmt(), sm, Kind.REFL_INVOKE, null);
}
}
}
}
}
}
use of soot.ArrayType in project soot by Sable.
the class OnFlyCallGraphBuilder method getImplicitTargets.
private void getImplicitTargets(SootMethod source) {
final SootClass scl = source.getDeclaringClass();
if (source.isNative() || source.isPhantom())
return;
if (source.getSubSignature().indexOf("<init>") >= 0) {
handleInit(source, scl);
}
Body b = source.retrieveActiveBody();
for (Unit u : b.getUnits()) {
final Stmt s = (Stmt) u;
if (s.containsInvokeExpr()) {
InvokeExpr ie = s.getInvokeExpr();
SootMethodRef methodRef = ie.getMethodRef();
switch(methodRef.declaringClass().getName()) {
case "java.lang.reflect.Method":
if (methodRef.getSubSignature().getString().equals("java.lang.Object invoke(java.lang.Object,java.lang.Object[])"))
reflectionModel.methodInvoke(source, s);
break;
case "java.lang.Class":
if (methodRef.getSubSignature().getString().equals("java.lang.Object newInstance()"))
reflectionModel.classNewInstance(source, s);
break;
case "java.lang.reflect.Constructor":
if (methodRef.getSubSignature().getString().equals("java.lang.Object newInstance(java.lang.Object[]))"))
reflectionModel.contructorNewInstance(source, s);
break;
}
if (methodRef.getSubSignature() == sigForName) {
reflectionModel.classForName(source, s);
}
if (ie instanceof StaticInvokeExpr) {
SootClass cl = ie.getMethodRef().declaringClass();
for (SootMethod clinit : EntryPoints.v().clinitsOf(cl)) {
addEdge(source, s, clinit, Kind.CLINIT);
}
}
}
if (s.containsFieldRef()) {
FieldRef fr = s.getFieldRef();
if (fr instanceof StaticFieldRef) {
SootClass cl = fr.getFieldRef().declaringClass();
for (SootMethod clinit : EntryPoints.v().clinitsOf(cl)) {
addEdge(source, s, clinit, Kind.CLINIT);
}
}
}
if (s instanceof AssignStmt) {
Value rhs = ((AssignStmt) s).getRightOp();
if (rhs instanceof NewExpr) {
NewExpr r = (NewExpr) rhs;
SootClass cl = r.getBaseType().getSootClass();
for (SootMethod clinit : EntryPoints.v().clinitsOf(cl)) {
addEdge(source, s, clinit, Kind.CLINIT);
}
} else if (rhs instanceof NewArrayExpr || rhs instanceof NewMultiArrayExpr) {
Type t = rhs.getType();
if (t instanceof ArrayType)
t = ((ArrayType) t).baseType;
if (t instanceof RefType) {
SootClass cl = ((RefType) t).getSootClass();
for (SootMethod clinit : EntryPoints.v().clinitsOf(cl)) {
addEdge(source, s, clinit, Kind.CLINIT);
}
}
}
}
}
}
use of soot.ArrayType in project soot by Sable.
the class ConstantArrayAnalysis method flowThrough.
@Override
protected void flowThrough(ArrayState in, Unit d, ArrayState out) {
out.active.clear();
out.active.or(in.active);
out.state = Arrays.copyOf(in.state, in.state.length);
if (d instanceof DefinitionStmt) {
DefinitionStmt ds = (DefinitionStmt) d;
Value rhs = ds.getRightOp();
Value lhs = ds.getLeftOp();
if (rhs instanceof NewArrayExpr) {
Local l = (Local) lhs;
int varRef = localToInt.get(l);
NewArrayExpr nae = (NewArrayExpr) rhs;
out.active.set(varRef);
if (!(nae.getSize() instanceof IntConstant)) {
out.state[varRef] = null;
} else {
int arraySize = ((IntConstant) nae.getSize()).value;
out.state[varRef] = new ArrayTypesInternal();
out.state[varRef].sizeState.set(sizeToInt.get(arraySize));
out.state[varRef].typeState = new BitSet[arraySize];
out.state[varRef].mustAssign = new BitSet(arraySize);
for (int i = 0; i < arraySize; i++) {
out.state[varRef].typeState[i] = new BitSet(typeSize);
}
}
} else if (lhs instanceof Local && lhs.getType() instanceof ArrayType && rhs instanceof NullConstant) {
int varRef = localToInt.get(lhs);
out.active.clear(varRef);
out.state[varRef] = null;
} else if (lhs instanceof Local && rhs instanceof Local && in.state[localToInt.get(rhs)] != null && in.active.get(localToInt.get(rhs))) {
int lhsRef = localToInt.get(lhs);
int rhsRef = localToInt.get(rhs);
out.active.set(lhsRef);
out.state[lhsRef] = in.state[rhsRef];
out.state[rhsRef] = null;
} else if (lhs instanceof Local && rhs instanceof PhiExpr) {
PhiExpr rPhi = (PhiExpr) rhs;
int lhsRef = localToInt.get(lhs);
out.state[lhsRef] = null;
int i = 0;
List<Value> phiValues = rPhi.getValues();
for (; i < phiValues.size(); i++) {
Value v = phiValues.get(i);
int argRef = localToInt.get(v);
if (!in.active.get(argRef)) {
continue;
}
out.active.set(lhsRef);
// one bottom -> all bottom
if (in.state[argRef] == null) {
out.state[lhsRef] = null;
break;
}
if (out.state[lhsRef] == null) {
out.state[lhsRef] = in.state[argRef];
} else {
out.state[lhsRef] = mergeTypeStates(in.state[argRef], out.state[lhsRef]);
}
out.state[argRef] = null;
}
for (; i < phiValues.size(); i++) {
int argRef = localToInt.get(phiValues.get(i));
out.state[argRef] = null;
}
} else if (lhs instanceof ArrayRef) {
ArrayRef ar = (ArrayRef) lhs;
Value indexVal = ar.getIndex();
int localRef = localToInt.get(ar.getBase());
if (!(indexVal instanceof IntConstant)) {
out.state[localRef] = null;
out.active.set(localRef);
} else if (out.state[localRef] != null) {
Type assignType = rhs.getType();
int index = ((IntConstant) indexVal).value;
assert index < out.state[localRef].typeState.length;
out.deepCloneLocalValueSlot(localRef, index);
assert out.state[localRef].typeState[index] != null : d;
out.state[localRef].typeState[index].set(typeToInt.get(assignType));
out.state[localRef].mustAssign.set(index);
}
} else {
Value leftOp = lhs;
if (leftOp instanceof Local) {
Local defLocal = (Local) leftOp;
int varRef = localToInt.get(defLocal);
out.active.set(varRef);
out.state[varRef] = null;
}
}
for (ValueBox b : rhs.getUseBoxes()) {
if (localToInt.containsKey(b.getValue())) {
int localRef = localToInt.get(b.getValue());
out.state[localRef] = null;
out.active.set(localRef);
}
}
if (localToInt.containsKey(rhs)) {
int localRef = localToInt.get(rhs);
out.state[localRef] = null;
out.active.set(localRef);
}
} else {
for (ValueBox b : d.getUseBoxes()) {
if (localToInt.containsKey(b.getValue())) {
int localRef = localToInt.get(b.getValue());
out.state[localRef] = null;
out.active.set(localRef);
}
}
}
}
use of soot.ArrayType in project soot by Sable.
the class ReflectiveCallsInliner method createNewMethod.
@SuppressWarnings("unchecked")
private SootMethod createNewMethod(Kind callKind, String target, Type fieldSetGetType) {
List<Type> parameterTypes = new LinkedList<Type>();
Type returnType = null;
switch(callKind) {
case ClassForName:
returnType = RefType.v("java.lang.Class");
break;
case ClassNewInstance:
returnType = RefType.v("java.lang.Object");
break;
case ConstructorNewInstance:
parameterTypes.add(ArrayType.v(RefType.v("java.lang.Object"), 1));
returnType = RefType.v("java.lang.Object");
break;
case MethodInvoke:
parameterTypes.add(RefType.v("java.lang.Object"));
parameterTypes.add(ArrayType.v(RefType.v("java.lang.Object"), 1));
returnType = RefType.v("java.lang.Object");
break;
case FieldSet:
parameterTypes.add(RefType.v("java.lang.Object"));
parameterTypes.add(fieldSetGetType);
returnType = VoidType.v();
break;
case FieldGet:
parameterTypes.add(RefType.v("java.lang.Object"));
returnType = fieldSetGetType;
break;
default:
throw new IllegalStateException();
}
SootMethod newMethod = Scene.v().makeSootMethod("reflectiveCall" + (callNum++), parameterTypes, returnType, Modifier.PUBLIC | Modifier.STATIC);
Body newBody = Jimple.v().newBody(newMethod);
newMethod.setActiveBody(newBody);
reflectiveCallsClass.addMethod(newMethod);
PatchingChain<Unit> newUnits = newBody.getUnits();
LocalGenerator localGen = new LocalGenerator(newBody);
Local freshLocal;
Value replacement = null;
Local[] paramLocals = null;
switch(callKind) {
case ClassForName:
{
// replace by: <Class constant for <target>>
freshLocal = localGen.generateLocal(RefType.v("java.lang.Class"));
replacement = ClassConstant.v(target.replace('.', '/'));
break;
}
case ClassNewInstance:
{
// replace by: new <target>
RefType targetType = RefType.v(target);
freshLocal = localGen.generateLocal(targetType);
replacement = Jimple.v().newNewExpr(targetType);
break;
}
case ConstructorNewInstance:
{
/*
* replace r=constr.newInstance(args) by: Object p0 = args[0]; ...
* Object pn = args[n]; T0 a0 = (T0)p0; ... Tn an = (Tn)pn;
*/
SootMethod constructor = Scene.v().getMethod(target);
paramLocals = new Local[constructor.getParameterCount()];
if (constructor.getParameterCount() > 0) {
// argArrayLocal = @parameter-0
ArrayType arrayType = ArrayType.v(RefType.v("java.lang.Object"), 1);
Local argArrayLocal = localGen.generateLocal(arrayType);
newUnits.add(Jimple.v().newIdentityStmt(argArrayLocal, Jimple.v().newParameterRef(arrayType, 0)));
int i = 0;
for (Type paramType : ((Collection<Type>) constructor.getParameterTypes())) {
paramLocals[i] = localGen.generateLocal(paramType);
unboxParameter(argArrayLocal, i, paramLocals, paramType, newUnits, localGen);
i++;
}
}
RefType targetType = constructor.getDeclaringClass().getType();
freshLocal = localGen.generateLocal(targetType);
replacement = Jimple.v().newNewExpr(targetType);
break;
}
case MethodInvoke:
{
/*
* replace r=m.invoke(obj,args) by: T recv = (T)obj; Object p0 =
* args[0]; ... Object pn = args[n]; T0 a0 = (T0)p0; ... Tn an =
* (Tn)pn;
*/
SootMethod method = Scene.v().getMethod(target);
// recvObject = @parameter-0
RefType objectType = RefType.v("java.lang.Object");
Local recvObject = localGen.generateLocal(objectType);
newUnits.add(Jimple.v().newIdentityStmt(recvObject, Jimple.v().newParameterRef(objectType, 0)));
paramLocals = new Local[method.getParameterCount()];
if (method.getParameterCount() > 0) {
// argArrayLocal = @parameter-1
ArrayType arrayType = ArrayType.v(RefType.v("java.lang.Object"), 1);
Local argArrayLocal = localGen.generateLocal(arrayType);
newUnits.add(Jimple.v().newIdentityStmt(argArrayLocal, Jimple.v().newParameterRef(arrayType, 1)));
int i = 0;
for (Type paramType : ((Collection<Type>) method.getParameterTypes())) {
paramLocals[i] = localGen.generateLocal(paramType);
unboxParameter(argArrayLocal, i, paramLocals, paramType, newUnits, localGen);
i++;
}
}
RefType targetType = method.getDeclaringClass().getType();
freshLocal = localGen.generateLocal(targetType);
replacement = Jimple.v().newCastExpr(recvObject, method.getDeclaringClass().getType());
break;
}
case FieldSet:
case FieldGet:
{
/*
* replace f.set(o,v) by: Object obj = @parameter-0; T freshLocal =
* (T)obj;
*/
RefType objectType = RefType.v("java.lang.Object");
Local recvObject = localGen.generateLocal(objectType);
newUnits.add(Jimple.v().newIdentityStmt(recvObject, Jimple.v().newParameterRef(objectType, 0)));
SootField field = Scene.v().getField(target);
freshLocal = localGen.generateLocal(field.getDeclaringClass().getType());
replacement = Jimple.v().newCastExpr(recvObject, field.getDeclaringClass().getType());
break;
}
default:
throw new InternalError("Unknown kind of reflective call " + callKind);
}
AssignStmt replStmt = Jimple.v().newAssignStmt(freshLocal, replacement);
newUnits.add(replStmt);
Local retLocal = localGen.generateLocal(returnType);
switch(callKind) {
case ClassForName:
{
// add: retLocal = freshLocal;
newUnits.add(Jimple.v().newAssignStmt(retLocal, freshLocal));
break;
}
case ClassNewInstance:
{
// add: freshLocal.<init>()
SootClass targetClass = Scene.v().getSootClass(target);
SpecialInvokeExpr constrCallExpr = Jimple.v().newSpecialInvokeExpr(freshLocal, Scene.v().makeMethodRef(targetClass, SootMethod.constructorName, Collections.<Type>emptyList(), VoidType.v(), false));
InvokeStmt constrCallStmt2 = Jimple.v().newInvokeStmt(constrCallExpr);
newUnits.add(constrCallStmt2);
// add: retLocal = freshLocal
newUnits.add(Jimple.v().newAssignStmt(retLocal, freshLocal));
break;
}
case ConstructorNewInstance:
{
// add: freshLocal.<target>(a0,...,an);
SootMethod constructor = Scene.v().getMethod(target);
SpecialInvokeExpr constrCallExpr = Jimple.v().newSpecialInvokeExpr(freshLocal, constructor.makeRef(), Arrays.asList(paramLocals));
InvokeStmt constrCallStmt2 = Jimple.v().newInvokeStmt(constrCallExpr);
newUnits.add(constrCallStmt2);
// add: retLocal = freshLocal
newUnits.add(Jimple.v().newAssignStmt(retLocal, freshLocal));
break;
}
case MethodInvoke:
{
// add: freshLocal=recv.<target>(a0,...,an);
SootMethod method = Scene.v().getMethod(target);
InvokeExpr invokeExpr;
if (method.isStatic())
invokeExpr = Jimple.v().newStaticInvokeExpr(method.makeRef(), Arrays.asList(paramLocals));
else
invokeExpr = Jimple.v().newVirtualInvokeExpr(freshLocal, method.makeRef(), Arrays.<Value>asList(paramLocals));
if (method.getReturnType().equals(VoidType.v())) {
// method returns null; simply invoke it and return null
InvokeStmt invokeStmt = Jimple.v().newInvokeStmt(invokeExpr);
newUnits.add(invokeStmt);
AssignStmt assignStmt = Jimple.v().newAssignStmt(retLocal, NullConstant.v());
newUnits.add(assignStmt);
} else {
AssignStmt assignStmt = Jimple.v().newAssignStmt(retLocal, invokeExpr);
newUnits.add(assignStmt);
}
break;
}
case FieldSet:
{
// add freshLocal.<f> = v;
Local value = localGen.generateLocal(fieldSetGetType);
newUnits.insertBeforeNoRedirect(Jimple.v().newIdentityStmt(value, Jimple.v().newParameterRef(fieldSetGetType, 1)), replStmt);
SootField field = Scene.v().getField(target);
Local boxedOrCasted = localGen.generateLocal(field.getType());
insertCastOrUnboxingCode(boxedOrCasted, value, newUnits);
FieldRef fieldRef;
if (field.isStatic()) {
fieldRef = Jimple.v().newStaticFieldRef(field.makeRef());
} else {
fieldRef = Jimple.v().newInstanceFieldRef(freshLocal, field.makeRef());
}
newUnits.add(Jimple.v().newAssignStmt(fieldRef, boxedOrCasted));
break;
}
case FieldGet:
{
/*
* add: T2 temp = recv.<f>; return temp;
*/
SootField field = Scene.v().getField(target);
Local value = localGen.generateLocal(field.getType());
FieldRef fieldRef;
if (field.isStatic()) {
fieldRef = Jimple.v().newStaticFieldRef(field.makeRef());
} else {
fieldRef = Jimple.v().newInstanceFieldRef(freshLocal, field.makeRef());
}
newUnits.add(Jimple.v().newAssignStmt(value, fieldRef));
insertCastOrBoxingCode(retLocal, value, newUnits);
break;
}
}
if (!returnType.equals(VoidType.v()))
newUnits.add(Jimple.v().newReturnStmt(retLocal));
if (Options.v().validate())
newBody.validate();
cleanup(newBody);
return newMethod;
}
Aggregations