use of soot.ArrayType in project soot by Sable.
the class DexTransformer method findArrayType.
protected Type findArrayType(LocalDefs localDefs, Stmt arrayStmt, int depth, Set<Unit> alreadyVisitedDefs) {
ArrayRef aRef = null;
if (arrayStmt.containsArrayRef()) {
aRef = arrayStmt.getArrayRef();
}
Local aBase = null;
if (null == aRef) {
if (arrayStmt instanceof AssignStmt) {
AssignStmt stmt = (AssignStmt) arrayStmt;
aBase = (Local) stmt.getRightOp();
} else {
throw new RuntimeException("ERROR: not an assign statement: " + arrayStmt);
}
} else {
aBase = (Local) aRef.getBase();
}
List<Unit> defsOfaBaseList = localDefs.getDefsOfAt(aBase, arrayStmt);
if (defsOfaBaseList == null || defsOfaBaseList.isEmpty()) {
throw new RuntimeException("ERROR: no def statement found for array base local " + arrayStmt);
}
// We should find an answer only by processing the first item of the
// list
Type aType = null;
int nullDefCount = 0;
for (Unit baseDef : defsOfaBaseList) {
if (alreadyVisitedDefs.contains(baseDef))
continue;
Set<Unit> newVisitedDefs = new HashSet<Unit>(alreadyVisitedDefs);
newVisitedDefs.add(baseDef);
// statement
if (baseDef instanceof AssignStmt) {
AssignStmt stmt = (AssignStmt) baseDef;
Value r = stmt.getRightOp();
if (r instanceof FieldRef) {
Type t = ((FieldRef) r).getFieldRef().type();
if (t instanceof ArrayType) {
ArrayType at = (ArrayType) t;
t = at.getArrayElementType();
}
if (depth == 0) {
aType = t;
break;
} else {
return t;
}
} else if (r instanceof ArrayRef) {
ArrayRef ar = (ArrayRef) r;
if (ar.getType().toString().equals(".unknown") || ar.getType().toString().equals("unknown")) {
// ||
// ar.getType())
// {
Type t = findArrayType(localDefs, stmt, ++depth, // TODO: which type should be
newVisitedDefs);
// returned?
if (t instanceof ArrayType) {
ArrayType at = (ArrayType) t;
t = at.getArrayElementType();
}
if (depth == 0) {
aType = t;
break;
} else {
return t;
}
} else {
ArrayType at = (ArrayType) stmt.getRightOp().getType();
Type t = at.getArrayElementType();
if (depth == 0) {
aType = t;
break;
} else {
return t;
}
}
} else if (r instanceof NewArrayExpr) {
NewArrayExpr expr = (NewArrayExpr) r;
Type t = expr.getBaseType();
if (depth == 0) {
aType = t;
break;
} else {
return t;
}
} else if (r instanceof CastExpr) {
Type t = (((CastExpr) r).getCastType());
if (t instanceof ArrayType) {
ArrayType at = (ArrayType) t;
t = at.getArrayElementType();
}
if (depth == 0) {
aType = t;
break;
} else {
return t;
}
} else if (r instanceof InvokeExpr) {
Type t = ((InvokeExpr) r).getMethodRef().returnType();
if (t instanceof ArrayType) {
ArrayType at = (ArrayType) t;
t = at.getArrayElementType();
}
if (depth == 0) {
aType = t;
break;
} else {
return t;
}
// introduces alias. We look whether there is any type
// information associated with the alias.
} else if (r instanceof Local) {
Type t = findArrayType(localDefs, stmt, ++depth, newVisitedDefs);
if (depth == 0) {
aType = t;
// break;
} else {
// return t;
aType = t;
}
} else if (r instanceof Constant) {
// If the right side is a null constant, we might have a
// case of broken code, e.g.,
// a = null;
// a[12] = 42;
nullDefCount++;
} else {
throw new RuntimeException("ERROR: def statement not possible! " + stmt);
}
} else if (baseDef instanceof IdentityStmt) {
IdentityStmt stmt = (IdentityStmt) baseDef;
ArrayType at = (ArrayType) stmt.getRightOp().getType();
Type t = at.getArrayElementType();
if (depth == 0) {
aType = t;
break;
} else {
return t;
}
} else {
throw new RuntimeException("ERROR: base local def must be AssignStmt or IdentityStmt! " + baseDef);
}
if (aType != null)
break;
}
if (depth == 0 && aType == null) {
if (nullDefCount == defsOfaBaseList.size()) {
return NullType.v();
} else {
throw new RuntimeException("ERROR: could not find type of array from statement '" + arrayStmt + "'");
}
} else
return aType;
}
use of soot.ArrayType in project soot by Sable.
the class DexlibWrapper method initialize.
public void initialize() {
// resolve classes in dex files
for (DexBackedDexFile dexFile : dexFiles) {
for (ClassDef defItem : dexFile.getClasses()) {
String forClassName = Util.dottedClassName(defItem.getType());
classesToDefItems.put(forClassName, new ClassInformation(dexFile, defItem));
}
}
// produce an error during type resolution.
for (DexBackedDexFile dexFile : dexFiles) {
for (int i = 0; i < dexFile.getTypeCount(); i++) {
String t = dexFile.getType(i);
Type st = DexType.toSoot(t);
if (st instanceof ArrayType) {
st = ((ArrayType) st).baseType;
}
String sootTypeName = st.toString();
if (!Scene.v().containsClass(sootTypeName)) {
if (st instanceof PrimType || st instanceof VoidType || systemAnnotationNames.contains(sootTypeName)) {
/*
* dex files contain references to the Type IDs of the
* system annotations. They are only visible to the
* Dalvik VM (for reflection, see
* vm/reflect/Annotations.cpp), and not to the user - so
* we do not want them to be resolved.
*/
continue;
}
SootResolver.v().makeClassRef(sootTypeName);
}
SootResolver.v().resolveClass(sootTypeName, SootClass.SIGNATURES);
}
}
}
use of soot.ArrayType in project soot by Sable.
the class Renamer method objectsGetClassName.
/*
* The method assigns any local whose name hasnt been changed yet to
* the name of the class type it belongs to
*/
private void objectsGetClassName() {
Iterator<Local> it = heuristics.getLocalsIterator();
while (it.hasNext()) {
Local tempLocal = it.next();
if (alreadyChanged(tempLocal)) {
continue;
}
debug("objectsGetClassName", "checking " + tempLocal);
Type type = tempLocal.getType();
if (type instanceof ArrayType) {
// should have been handled by arraysGetTypeArray heuristic
continue;
}
if (type instanceof RefLikeType) {
debug("objectsGetClassName", "Local:" + tempLocal + " Type: " + type.toString());
// debug("objectsGetClassName","getting array type"+type.getArrayType());
String tempClassName = type.toString();
// debug("objectsGetClassName","type of object is"+tempClassName);
if (tempClassName.indexOf('.') != -1) {
// contains a dot have to remove that
tempClassName = tempClassName.substring(tempClassName.lastIndexOf('.') + 1);
}
String newName = tempClassName.toLowerCase();
int count = 0;
newName += count;
count++;
while (!isUniqueName(newName)) {
newName = newName.substring(0, newName.length() - 1) + count;
count++;
}
setName(tempLocal, newName);
}
}
}
use of soot.ArrayType in project soot by Sable.
the class FilledNewArrayInstruction method jimplify.
@Override
public void jimplify(DexBody body) {
if (!(instruction instanceof Instruction35c))
throw new IllegalArgumentException("Expected Instruction35c but got: " + instruction.getClass());
Instruction35c filledNewArrayInstr = (Instruction35c) instruction;
int[] regs = { filledNewArrayInstr.getRegisterC(), filledNewArrayInstr.getRegisterD(), filledNewArrayInstr.getRegisterE(), filledNewArrayInstr.getRegisterF(), filledNewArrayInstr.getRegisterG() };
// NopStmt nopStmtBeginning = Jimple.v().newNopStmt();
// body.add(nopStmtBeginning);
int usedRegister = filledNewArrayInstr.getRegisterCount();
Type t = DexType.toSoot((TypeReference) filledNewArrayInstr.getReference());
// NewArrayExpr needs the ElementType as it increases the array dimension by 1
Type arrayType = ((ArrayType) t).getElementType();
NewArrayExpr arrayExpr = Jimple.v().newNewArrayExpr(arrayType, IntConstant.v(usedRegister));
// new local generated intentional, will be moved to real register by MoveResult
Local arrayLocal = body.getStoreResultLocal();
AssignStmt assign = Jimple.v().newAssignStmt(arrayLocal, arrayExpr);
body.add(assign);
for (int i = 0; i < usedRegister; i++) {
ArrayRef arrayRef = Jimple.v().newArrayRef(arrayLocal, IntConstant.v(i));
AssignStmt assign2 = Jimple.v().newAssignStmt(arrayRef, body.getRegisterLocal(regs[i]));
addTags(assign2);
body.add(assign2);
}
// NopStmt nopStmtEnd = Jimple.v().newNopStmt();
// body.add(nopStmtEnd);
// defineBlock(nopStmtBeginning, nopStmtEnd);
setUnit(assign);
if (IDalvikTyper.ENABLE_DVKTYPER) {
// Debug.printDbg(IDalvikTyper.DEBUG, "constraint: "+ assign);
DalvikTyper.v().setType(assign.getLeftOpBox(), arrayExpr.getType(), false);
// DalvikTyper.v().setType(array, arrayType, isUse)
// DalvikTyper.v().addConstraint(assign.getLeftOpBox(), assign.getRightOpBox());
}
}
use of soot.ArrayType in project soot by Sable.
the class TypeResolver method applyAssignmentConstraints.
private Collection<Typing> applyAssignmentConstraints(Typing tg, IEvalFunction ef, IHierarchy h) {
final int numAssignments = this.assignments.size();
LinkedList<Typing> sigma = new LinkedList<Typing>(), r = new LinkedList<Typing>();
if (numAssignments == 0)
return sigma;
HashMap<Typing, BitSet> worklists = new HashMap<Typing, BitSet>();
sigma.add(tg);
BitSet wl = new BitSet(numAssignments - 1);
wl.set(0, numAssignments);
worklists.put(tg, wl);
while (!sigma.isEmpty()) {
tg = sigma.element();
wl = worklists.get(tg);
if (wl.isEmpty()) {
r.add(tg);
sigma.remove();
worklists.remove(tg);
} else {
// Get the next definition statement
int defIdx = wl.nextSetBit(0);
wl.clear(defIdx);
DefinitionStmt stmt = this.assignments.get(defIdx);
Value lhs = stmt.getLeftOp(), rhs = stmt.getRightOp();
Local v;
if (lhs instanceof Local)
v = (Local) lhs;
else
v = (Local) ((ArrayRef) lhs).getBase();
Type told = tg.get(v);
Collection<Type> eval = new ArrayList<Type>(ef.eval(tg, rhs, stmt));
boolean isFirstType = true;
for (Type t_ : eval) {
if (lhs instanceof ArrayRef) {
/* We only need to consider array references on the LHS
of assignments where there is supertyping between array
types, which is only for arrays of reference types and
multidimensional arrays. */
if (!(t_ instanceof RefType || t_ instanceof ArrayType)) {
continue;
}
t_ = t_.makeArrayType();
}
// Special handling for exception objects with phantom types
final Collection<Type> lcas;
if (!typesEqual(told, t_) && told instanceof RefType && t_ instanceof RefType && (((RefType) told).getSootClass().isPhantom() || ((RefType) t_).getSootClass().isPhantom()) && (stmt.getRightOp() instanceof CaughtExceptionRef))
lcas = Collections.<Type>singleton(RefType.v("java.lang.Throwable"));
else
lcas = h.lcas(told, t_);
for (Type t : lcas) {
if (!typesEqual(t, told)) {
Typing tg_;
BitSet wl_;
if (/*(eval.size() == 1 && lcas.size() == 1) ||*/
isFirstType) {
// The types agree, we have a type we can directly use
tg_ = tg;
wl_ = wl;
} else {
// The types do not agree, add all supertype candidates
tg_ = new Typing(tg);
wl_ = new BitSet(numAssignments - 1);
wl_.or(wl);
sigma.add(tg_);
worklists.put(tg_, wl_);
}
tg_.set(v, t);
BitSet dependsV = this.depends.get(v);
if (dependsV != null)
wl_.or(dependsV);
}
isFirstType = false;
}
}
// end for
}
}
Typing.minimize(r, h);
return r;
}
Aggregations