use of soot.javaToJimple.LocalGenerator in project soot by Sable.
the class SootMethodRefImpl method createUnresolvedErrorMethod.
/**
* Creates a method body that throws an "unresolved compilation error" message
*
* @param declaringClass
* The class that was supposed to contain the method
* @return The created SootMethod
*/
private SootMethod createUnresolvedErrorMethod(SootClass declaringClass) {
SootMethod m = Scene.v().makeSootMethod(name, parameterTypes, returnType, isStatic() ? Modifier.STATIC : 0);
// we don't know who will be calling us
int modifiers = Modifier.PUBLIC;
if (isStatic())
modifiers |= Modifier.STATIC;
m.setModifiers(modifiers);
JimpleBody body = Jimple.v().newBody(m);
m.setActiveBody(body);
final LocalGenerator lg = new LocalGenerator(body);
// For producing valid Jimple code, we need to access all parameters.
// Otherwise, methods like "getThisLocal()" will fail.
body.insertIdentityStmts(declaringClass);
// exc = new Error
RefType runtimeExceptionType = RefType.v("java.lang.Error");
NewExpr newExpr = Jimple.v().newNewExpr(runtimeExceptionType);
Local exceptionLocal = lg.generateLocal(runtimeExceptionType);
AssignStmt assignStmt = Jimple.v().newAssignStmt(exceptionLocal, newExpr);
body.getUnits().add(assignStmt);
// exc.<init>(message)
SootMethodRef cref = Scene.v().makeConstructorRef(runtimeExceptionType.getSootClass(), Collections.<Type>singletonList(RefType.v("java.lang.String")));
SpecialInvokeExpr constructorInvokeExpr = Jimple.v().newSpecialInvokeExpr(exceptionLocal, cref, StringConstant.v("Unresolved compilation error: Method " + getSignature() + " does not exist!"));
InvokeStmt initStmt = Jimple.v().newInvokeStmt(constructorInvokeExpr);
body.getUnits().insertAfter(initStmt, assignStmt);
// throw exc
body.getUnits().insertAfter(Jimple.v().newThrowStmt(exceptionLocal), initStmt);
return declaringClass.getOrAddMethod(m);
}
use of soot.javaToJimple.LocalGenerator in project soot by Sable.
the class AccessManager method createGetAccessor.
private static void createGetAccessor(SootMethod container, AssignStmt as, FieldRef ref) {
java.util.List parameterTypes = new LinkedList();
java.util.List<SootClass> thrownExceptions = new LinkedList<SootClass>();
Body accessorBody = Jimple.v().newBody();
soot.util.Chain accStmts = accessorBody.getUnits();
LocalGenerator lg = new LocalGenerator(accessorBody);
Body containerBody = container.getActiveBody();
soot.util.Chain containerStmts = containerBody.getUnits();
SootClass target = ref.getField().getDeclaringClass();
SootMethod accessor;
String name = createAccessorName(ref.getField(), false);
accessor = target.getMethodByNameUnsafe(name);
if (accessor == null) {
Type returnType = ref.getField().getType();
Local thisLocal = lg.generateLocal(target.getType());
if (ref instanceof InstanceFieldRef) {
parameterTypes.add(target.getType());
accStmts.addFirst(Jimple.v().newIdentityStmt(thisLocal, Jimple.v().newParameterRef(target.getType(), 0)));
}
Local l = lg.generateLocal(ref.getField().getType());
Value v;
if (ref instanceof InstanceFieldRef) {
v = Jimple.v().newInstanceFieldRef(thisLocal, ref.getFieldRef());
} else {
v = Jimple.v().newStaticFieldRef(ref.getFieldRef());
}
accStmts.add(Jimple.v().newAssignStmt(l, v));
accStmts.add(Jimple.v().newReturnStmt(l));
accessor = Scene.v().makeSootMethod(name, parameterTypes, returnType, Modifier.PUBLIC | Modifier.STATIC, thrownExceptions);
accessorBody.setMethod(accessor);
accessor.setActiveBody(accessorBody);
target.addMethod(accessor);
}
java.util.List args = new LinkedList();
if (ref instanceof InstanceFieldRef) {
args.add(((InstanceFieldRef) ref).getBase());
}
InvokeExpr newExpr = Jimple.v().newStaticInvokeExpr(accessor.makeRef(), args);
as.setRightOp(newExpr);
}
use of soot.javaToJimple.LocalGenerator 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;
}
use of soot.javaToJimple.LocalGenerator in project soot by Sable.
the class AccessManager method createInvokeAccessor.
private static void createInvokeAccessor(SootMethod container, Stmt stmt) {
java.util.List parameterTypes = new LinkedList();
java.util.List<SootClass> thrownExceptions = new LinkedList<SootClass>();
Type returnType;
Body accessorBody = Jimple.v().newBody();
soot.util.Chain accStmts = accessorBody.getUnits();
LocalGenerator lg = new LocalGenerator(accessorBody);
Body containerBody = container.getActiveBody();
soot.util.Chain containerStmts = containerBody.getUnits();
InvokeExpr expr = stmt.getInvokeExpr();
SootMethod method = expr.getMethod();
// System.out.println("method: " + method);
SootClass target = method.getDeclaringClass();
// System.out.println("target: " + target);
// System.out.println("method ref: " + expr.getMethodRef());
SootMethod accessor;
String name = createAccessorName(method, true);
accessor = target.getMethodByNameUnsafe(name);
if (accessor == null) {
java.util.List arguments = new LinkedList();
if (expr instanceof InstanceInvokeExpr) {
parameterTypes.add(target.getType());
}
parameterTypes.addAll(method.getParameterTypes());
returnType = method.getReturnType();
thrownExceptions.addAll(method.getExceptions());
int paramID = 0;
for (java.util.Iterator it = parameterTypes.iterator(); it.hasNext(); ) {
Type type = (Type) it.next();
Local l = lg.generateLocal(type);
// System.out.println("local type: " + type);
accStmts.add(Jimple.v().newIdentityStmt(l, Jimple.v().newParameterRef(type, paramID)));
arguments.add(l);
paramID++;
}
InvokeExpr accExpr;
if (expr instanceof StaticInvokeExpr) {
accExpr = Jimple.v().newStaticInvokeExpr(method.makeRef(), arguments);
} else if (expr instanceof VirtualInvokeExpr) {
Local thisLocal = (Local) arguments.get(0);
arguments.remove(0);
accExpr = Jimple.v().newVirtualInvokeExpr(thisLocal, method.makeRef(), arguments);
} else if (expr instanceof SpecialInvokeExpr) {
Local thisLocal = (Local) arguments.get(0);
arguments.remove(0);
accExpr = Jimple.v().newSpecialInvokeExpr(thisLocal, method.makeRef(), arguments);
} else
throw new RuntimeException("");
Stmt s;
if (returnType instanceof VoidType) {
s = Jimple.v().newInvokeStmt(accExpr);
accStmts.add(s);
accStmts.add(Jimple.v().newReturnVoidStmt());
} else {
Local resultLocal = lg.generateLocal(returnType);
s = Jimple.v().newAssignStmt(resultLocal, accExpr);
accStmts.add(s);
accStmts.add(Jimple.v().newReturnStmt(resultLocal));
}
accessor = Scene.v().makeSootMethod(name, parameterTypes, returnType, Modifier.PUBLIC | Modifier.STATIC, thrownExceptions);
accessorBody.setMethod(accessor);
accessor.setActiveBody(accessorBody);
target.addMethod(accessor);
}
java.util.List args = new LinkedList();
if (expr instanceof InstanceInvokeExpr) {
args.add(((InstanceInvokeExpr) expr).getBase());
}
args.addAll(expr.getArgs());
InvokeExpr newExpr = Jimple.v().newStaticInvokeExpr(accessor.makeRef(), args);
stmt.getInvokeExprBox().setValue(newExpr);
}
use of soot.javaToJimple.LocalGenerator in project soot by Sable.
the class AccessManager method createSetAccessor.
private static void createSetAccessor(SootMethod container, AssignStmt as, FieldRef ref) {
java.util.List parameterTypes = new LinkedList();
java.util.List<SootClass> thrownExceptions = new LinkedList<SootClass>();
Body accessorBody = Jimple.v().newBody();
soot.util.Chain accStmts = accessorBody.getUnits();
LocalGenerator lg = new LocalGenerator(accessorBody);
Body containerBody = container.getActiveBody();
soot.util.Chain containerStmts = containerBody.getUnits();
SootClass target = ref.getField().getDeclaringClass();
SootMethod accessor;
String name = createAccessorName(ref.getField(), true);
accessor = target.getMethodByNameUnsafe(name);
if (accessor == null) {
Local thisLocal = lg.generateLocal(target.getType());
int paramID = 0;
if (ref instanceof InstanceFieldRef) {
accStmts.add(Jimple.v().newIdentityStmt(thisLocal, Jimple.v().newParameterRef(target.getType(), paramID)));
parameterTypes.add(target.getType());
paramID++;
}
parameterTypes.add(ref.getField().getType());
Local l = lg.generateLocal(ref.getField().getType());
accStmts.add(Jimple.v().newIdentityStmt(l, Jimple.v().newParameterRef(ref.getField().getType(), paramID)));
paramID++;
if (ref instanceof InstanceFieldRef) {
accStmts.add(Jimple.v().newAssignStmt(Jimple.v().newInstanceFieldRef(thisLocal, ref.getFieldRef()), l));
} else {
accStmts.add(Jimple.v().newAssignStmt(Jimple.v().newStaticFieldRef(ref.getFieldRef()), l));
}
accStmts.addLast(Jimple.v().newReturnVoidStmt());
Type returnType = VoidType.v();
accessor = Scene.v().makeSootMethod(name, parameterTypes, returnType, Modifier.PUBLIC | Modifier.STATIC, thrownExceptions);
accessorBody.setMethod(accessor);
accessor.setActiveBody(accessorBody);
target.addMethod(accessor);
}
java.util.List args = new LinkedList();
if (ref instanceof InstanceFieldRef) {
args.add(((InstanceFieldRef) ref).getBase());
}
args.add(as.getRightOp());
InvokeExpr newExpr = Jimple.v().newStaticInvokeExpr(accessor.makeRef(), args);
Stmt newStmt = Jimple.v().newInvokeStmt(newExpr);
containerStmts.insertAfter(newStmt, as);
containerStmts.remove(as);
}
Aggregations