use of soot.SootField in project soot by Sable.
the class ClassResolver method addFinals.
private void addFinals(polyglot.types.LocalInstance li, ArrayList<SootField> finalFields) {
// add as param for init
for (SootMethod meth : sootClass.getMethods()) {
if (meth.getName().equals("<init>")) {
List<soot.Type> newParams = new ArrayList<soot.Type>();
newParams.addAll(meth.getParameterTypes());
newParams.add(Util.getSootType(li.type()));
meth.setParameterTypes(newParams);
}
}
// add field
soot.SootField sf = Scene.v().makeSootField("val$" + li.name(), Util.getSootType(li.type()), soot.Modifier.FINAL | soot.Modifier.PRIVATE);
sootClass.addField(sf);
finalFields.add(sf);
sf.addTag(new soot.tagkit.SyntheticTag());
}
use of soot.SootField in project soot by Sable.
the class ClassResolver method handleClassLiteral.
private void handleClassLiteral(polyglot.ast.ClassBody cBody) {
// check for class lits whose type is not primitive
ClassLiteralChecker classLitChecker = new ClassLiteralChecker();
cBody.visit(classLitChecker);
ArrayList<Node> classLitList = classLitChecker.getList();
if (!classLitList.isEmpty()) {
soot.SootClass addToClass = sootClass;
if (addToClass.isInterface()) {
addToClass = getSpecialInterfaceAnonClass(addToClass);
}
// add class$ meth
String methodName = "class$";
soot.Type methodRetType = soot.RefType.v("java.lang.Class");
ArrayList paramTypes = new ArrayList();
paramTypes.add(soot.RefType.v("java.lang.String"));
soot.SootMethod sootMethod = Scene.v().makeSootMethod(methodName, paramTypes, methodRetType, soot.Modifier.STATIC);
ClassLiteralMethodSource mSrc = new ClassLiteralMethodSource();
sootMethod.setSource(mSrc);
if (!addToClass.declaresMethod(methodName, paramTypes, methodRetType)) {
addToClass.addMethod(sootMethod);
sootMethod.addTag(new soot.tagkit.SyntheticTag());
}
// add fields for all non prim class lits
Iterator<Node> classLitIt = classLitList.iterator();
while (classLitIt.hasNext()) {
polyglot.ast.ClassLit classLit = (polyglot.ast.ClassLit) classLitIt.next();
// field
String fieldName = Util.getFieldNameForClassLit(classLit.typeNode().type());
soot.Type fieldType = soot.RefType.v("java.lang.Class");
soot.SootField sootField = Scene.v().makeSootField(fieldName, fieldType, soot.Modifier.STATIC);
if (!addToClass.declaresField(fieldName, fieldType)) {
addToClass.addField(sootField);
sootField.addTag(new soot.tagkit.SyntheticTag());
}
}
}
}
use of soot.SootField in project soot by Sable.
the class ClassResolver method addFinalLocals.
private ArrayList<SootField> addFinalLocals(polyglot.ast.ClassBody cBody, ArrayList<IdentityKey> finalLocalsAvail, polyglot.types.ClassType nodeKeyType, AnonLocalClassInfo info) {
ArrayList<SootField> finalFields = new ArrayList<SootField>();
LocalUsesChecker luc = new LocalUsesChecker();
cBody.visit(luc);
/* Iterator localsNeededIt = luc.getLocals().iterator(); */
ArrayList<IdentityKey> localsUsed = new ArrayList<IdentityKey>();
/*
* while (localsNeededIt.hasNext()){ polyglot.types.LocalInstance li =
* (polyglot.types.LocalInstance)((polyglot.util.IdentityKey)
* localsNeededIt.next()).object(); //if
* (luc.getLocalDecls().contains(new polyglot.util.IdentityKey(li))){
* //} //else { //} if (finalLocalsAvail.contains(new
* polyglot.util.IdentityKey(li)) && !luc.getLocalDecls().contains(new
* polyglot.util.IdentityKey(li))){
*
* addFinals(li,finalFields);
*
* localsUsed.add(new polyglot.util.IdentityKey(li)); } }
*/
Iterator<IdentityKey> fieldsNeededIt = finalLocalsAvail.iterator();
while (fieldsNeededIt.hasNext()) {
polyglot.types.LocalInstance li = (polyglot.types.LocalInstance) fieldsNeededIt.next().object();
if (!luc.getLocalDecls().contains(new polyglot.util.IdentityKey(li))) {
localsUsed.add(new polyglot.util.IdentityKey(li));
addFinals(li, finalFields);
}
}
// this part is broken it adds all final locals available for the new
// not just the ones used (which is a problem)
Iterator<Node> newsIt = luc.getNews().iterator();
while (newsIt.hasNext()) {
polyglot.ast.New tempNew = (polyglot.ast.New) newsIt.next();
polyglot.types.ClassType tempNewType = (polyglot.types.ClassType) tempNew.objectType().type();
if (InitialResolver.v().finalLocalInfo().containsKey(new polyglot.util.IdentityKey(tempNewType))) {
AnonLocalClassInfo lInfo = InitialResolver.v().finalLocalInfo().get(new polyglot.util.IdentityKey(tempNewType));
Iterator<IdentityKey> it = lInfo.finalLocalsAvail().iterator();
while (it.hasNext()) {
polyglot.types.LocalInstance li2 = (polyglot.types.LocalInstance) it.next().object();
if (!sootClass.declaresField("val$" + li2.name(), Util.getSootType(li2.type()))) {
if (!luc.getLocalDecls().contains(new polyglot.util.IdentityKey(li2))) {
addFinals(li2, finalFields);
localsUsed.add(new polyglot.util.IdentityKey(li2));
}
}
}
}
}
// also need to add them if any super class all the way up needs one
// because the super() will be made in init and it will require
// possibly eventually to send in the finals
polyglot.types.ClassType superType = (polyglot.types.ClassType) nodeKeyType.superType();
while (!Util.getSootType(superType).equals(soot.Scene.v().getSootClass("java.lang.Object").getType())) {
if (InitialResolver.v().finalLocalInfo().containsKey(new polyglot.util.IdentityKey(superType))) {
AnonLocalClassInfo lInfo = InitialResolver.v().finalLocalInfo().get(new polyglot.util.IdentityKey(superType));
Iterator<IdentityKey> it = lInfo.finalLocalsAvail().iterator();
while (it.hasNext()) {
polyglot.types.LocalInstance li2 = (polyglot.types.LocalInstance) it.next().object();
if (!sootClass.declaresField("val$" + li2.name(), Util.getSootType(li2.type()))) {
if (!luc.getLocalDecls().contains(new polyglot.util.IdentityKey(li2))) {
addFinals(li2, finalFields);
localsUsed.add(new polyglot.util.IdentityKey(li2));
}
}
}
}
superType = (polyglot.types.ClassType) superType.superType();
}
info.finalLocalsUsed(localsUsed);
InitialResolver.v().finalLocalInfo().put(new polyglot.util.IdentityKey(nodeKeyType), info);
return finalFields;
}
use of soot.SootField in project soot by Sable.
the class JimpleBodyBuilder method createJimpleBody.
/**
* Jimple Body Creation
*/
@Override
public soot.jimple.JimpleBody createJimpleBody(polyglot.ast.Block block, List formals, soot.SootMethod sootMethod) {
createBody(sootMethod);
lg = new LocalGenerator(body);
// create this formal except for static methods
if (!soot.Modifier.isStatic(sootMethod.getModifiers())) {
soot.RefType type = sootMethod.getDeclaringClass().getType();
specialThisLocal = soot.jimple.Jimple.v().newLocal("this", type);
body.getLocals().add(specialThisLocal);
soot.jimple.ThisRef thisRef = soot.jimple.Jimple.v().newThisRef(type);
soot.jimple.Stmt thisStmt = soot.jimple.Jimple.v().newIdentityStmt(specialThisLocal, thisRef);
body.getUnits().add(thisStmt);
// this is causing problems - no this in java code -> no tags
// Util.addLineTag(thisStmt, block);
}
int formalsCounter = 0;
// create outer class this param ref for inner classes except for static
// inner classes - this is not needed
int outerIndex = sootMethod.getDeclaringClass().getName().lastIndexOf("$");
if ((outerIndex != -1) && (sootMethod.getName().equals("<init>"))) {
SootField this0Field = sootMethod.getDeclaringClass().getFieldByNameUnsafe("this$0");
if (this0Field != null) {
// we know its an inner non static class can get outer class
// from field ref of the this$0 field
soot.SootClass outerClass = ((soot.RefType) this0Field.getType()).getSootClass();
soot.Local outerLocal = lg.generateLocal(outerClass.getType());
soot.jimple.ParameterRef paramRef = soot.jimple.Jimple.v().newParameterRef(outerClass.getType(), formalsCounter);
paramRefCount++;
soot.jimple.Stmt stmt = soot.jimple.Jimple.v().newIdentityStmt(outerLocal, paramRef);
stmt.addTag(new soot.tagkit.EnclosingTag());
body.getUnits().add(stmt);
((soot.javaToJimple.PolyglotMethodSource) sootMethod.getSource()).setOuterClassThisInit(outerLocal);
outerClassParamLocal = outerLocal;
formalsCounter++;
}
}
// handle formals
if (formals != null) {
String[] formalNames = new String[formals.size()];
Iterator formalsIt = formals.iterator();
while (formalsIt.hasNext()) {
polyglot.ast.Formal formal = (polyglot.ast.Formal) formalsIt.next();
createFormal(formal, formalsCounter);
formalNames[formalsCounter] = formal.name();
formalsCounter++;
}
body.getMethod().addTag(new soot.tagkit.ParamNamesTag(formalNames));
}
// handle final local params
ArrayList<SootField> finalsList = ((PolyglotMethodSource) body.getMethod().getSource()).getFinalsList();
if (finalsList != null) {
Iterator<SootField> finalsIt = finalsList.iterator();
while (finalsIt.hasNext()) {
soot.SootField sf = finalsIt.next();
soot.jimple.ParameterRef paramRef = soot.jimple.Jimple.v().newParameterRef(sf.getType(), formalsCounter);
paramRefCount++;
soot.jimple.Stmt stmt = soot.jimple.Jimple.v().newIdentityStmt(lg.generateLocal(sf.getType()), paramRef);
body.getUnits().add(stmt);
formalsCounter++;
}
}
createBlock(block);
// if method is <clinit> handle static field inits
if (sootMethod.getName().equals("<clinit>")) {
handleAssert(sootMethod);
handleStaticFieldInits(sootMethod);
handleStaticInitializerBlocks(sootMethod);
}
// determine if body has a return stmt
boolean hasReturn = false;
if (block != null) {
Iterator it = block.statements().iterator();
while (it.hasNext()) {
Object next = it.next();
if (next instanceof polyglot.ast.Return) {
hasReturn = true;
}
}
}
soot.Type retType = body.getMethod().getReturnType();
// only do this if noexplicit return
if ((!hasReturn) && (retType instanceof soot.VoidType)) {
soot.jimple.Stmt retStmt = soot.jimple.Jimple.v().newReturnVoidStmt();
body.getUnits().add(retStmt);
}
// add exceptions from exceptionTable
if (exceptionTable != null) {
Iterator<Trap> trapsIt = exceptionTable.iterator();
while (trapsIt.hasNext()) {
body.getTraps().add(trapsIt.next());
}
}
return body;
}
use of soot.SootField in project soot by Sable.
the class CollectConstants method internalTransform.
protected void internalTransform(String phaseName, Map<String, String> options) {
if (output) {
out.println("Collecting Constant Data");
}
BodyBuilder.retrieveAllNames();
Chain<SootClass> appClasses = Scene.v().getApplicationClasses();
for (SootClass sc : appClasses) {
for (SootMethod m : sc.getMethods()) {
if (!m.hasActiveBody() || m.getName().contains(SootMethod.staticInitializerName)) {
continue;
}
for (ValueBox useBox : m.getActiveBody().getUseBoxes()) {
Value v = useBox.getValue();
if (v instanceof Constant) {
Constant constant = (Constant) v;
Type type = constant.getType();
List<Constant> constants = typesToValues.computeIfAbsent(type, t -> new ArrayList<>());
if (!constants.contains(constant)) {
this.constants++;
constants.add(constant);
}
}
}
}
}
int count = 0;
String name = "newConstantJbcoName";
SootClass[] classes = appClasses.toArray(new SootClass[appClasses.size()]);
for (Type type : typesToValues.keySet()) {
if (type instanceof NullType) {
// type = RefType.v("java.lang.Object");
continue;
}
for (Constant constant : typesToValues.get(type)) {
name += "_";
SootClass randomClass;
do {
randomClass = classes[Rand.getInt(classes.length)];
} while (!isSuitableClassToAddFieldConstant(randomClass, constant));
SootField newField = Scene.v().makeSootField(FieldRenamer.getNewName(), type, Modifier.STATIC ^ Modifier.PUBLIC);
randomClass.addField(newField);
FieldRenamer.sootFieldsRenamed.add(newField);
FieldRenamer.addOldAndNewName(name, newField.getName());
constantsToFields.put(constant, newField);
addInitializingValue(randomClass, newField, constant);
FieldRenamer.addOldAndNewName("addedConstant" + count++, newField.getName());
}
}
updatedConstants += count;
}
Aggregations