private List<IField> collectFields() { List<IField> fields = new ArrayList<>(); Iterator<IClass> itr = cha.iterator(); while (itr.hasNext()) { IClass cls = itr.next(); for (IField field : cls.getAllStaticFields()) { if (field.getFieldTypeReference().isReferenceType()) { fields.add(field); } } } return fields; }
@Override public Collection<IField> getDeclaredStaticFields() { Set<IField> result = HashSetFactory.make(); for (IField F : declaredFields.values()) { if (F.isStatic()) { result.add(F); } } return result; }
@Override public PointerKey getPointerKeyForInstanceField(InstanceKey I, IField field) { if (field == null) { throw new IllegalArgumentException("field is null"); } IField resolveAgain = I.getConcreteType().getField(field.getName(), field.getFieldTypeReference().getName()); if (resolveAgain != null) { field = resolveAgain; } return new InstanceFieldKey(I, field); }
@Override public String descString() { return field.getDeclaringClass().toString() + '.' + field.getName().toString(); }
for (IField f : klass.getDeclaredInstanceFields()) { int tempValue = nextLocal++; SSAGetInstruction G = insts.GetInstruction(statements.size(), tempValue, 1, f.getReference()); statements.add(G); SSAPutInstruction P = insts.PutInstruction(statements.size(), retValue, tempValue, f.getReference()); statements.add(P);
public void visitPutInternal(int rval, int ref, boolean isStatic, FieldReference field) { if (DEBUG) { System.err.println("visitPut " + field); } // skip putfields of primitive type if (field.getFieldType().isPrimitiveType()) { return; } IField f = getClassHierarchy().resolveField(field); if (f == null) { if (DEBUG) { System.err.println("Could not resolve field " + field); } Warnings.add(FieldResolutionFailure.create(field)); return; } assert f.getFieldTypeReference().getName().equals(field.getFieldType().getName()) : "name clash of two fields with the same name but different type: " + f.getReference() + " <=> " + field; assert isStatic || !symbolTable.isStringConstant(ref) : "put to string constant shouldn't be allowed?"; if (isStatic) { processPutStatic(rval, field, f); } else { processPutField(rval, ref, f); } }
private Map<PointerKey, Object> computePointerKeys(IClass klass) { Map<PointerKey, Object> result = HashMapFactory.make(); if (klass.isArrayClass()) { ArrayClass a = (ArrayClass) klass; if (a.getElementClass() != null && a.getElementClass().isReferenceType()) { PointerKey p = pointerKeys.getPointerKeyForArrayContents(new ConcreteTypeKey(a)); result.put(p, p); } } else { for (IField f : klass.getAllFields()) { if (!f.getFieldTypeReference().isPrimitiveType()) { if (f.isStatic()) { PointerKey p = pointerKeys.getPointerKeyForStaticField(f); result.put(p, p); } else { PointerKey p = pointerKeys.getPointerKeyForInstanceField(new ConcreteTypeKey(klass), f); result.put(p, p); } } } } return result; }
assert(f.isStatic()) : "All fields of AndroidModelClass are expected to be static! " + f + " is not."; final TypeReference fdType = f.getReference().getFieldType(); final VariableKey subKey = new SSAValue.WeaklyNamedKey(fdType.getName(), "ctx" + fdType.getName().getClassName().toString()); instance = this.pm.getUnallocated(fdType, subKey); final SSAInstruction getInst = instructionFactory.GetInstruction(pc, instance, f.getReference()); this.body.addStatement(getInst); this.pm.setAllocation(instance, getInst);
@Override public boolean shouldRefine(IField field, PointerKey basePtr, PointerKey val, IFlowLabel label, StateMachine.State state) { if (field == null) { throw new IllegalArgumentException("null field"); } if (field == ArrayContents.v()) { return true; } else { final IClass declaringClass = field.getDeclaringClass(); final Matcher m = refinePattern.matcher(declaringClass.toString()); final boolean foundPattern = m.find(); recordDecision(declaringClass, foundPattern); return foundPattern; } }
/** * This main program shows one example use of thread escape analysis: producing a set of fields to be monitored for a * dynamic race detector. The idea is that any field might have a race with two exceptions: final fields do not have * races since there are no writes to them, and volatile fields have atomic read and write semantics provided by the * VM. Hence, this piece of code produces a list of all other fields. */ public static void main(String[] args) throws IOException, IllegalArgumentException, CancelException { String mainClassName = args[0]; Set<JarFile> jars = HashSetFactory.make(); for (int i = 1; i < args.length; i++) { jars.add(new JarFile(args[i], false)); } Set<IClass> escapingTypes = (new SimpleThreadEscapeAnalysis(jars, mainClassName)).gatherThreadEscapingClasses(); for (IClass cls : escapingTypes) { if (!cls.isArrayClass()) { for (IField f : cls.getAllFields()) { if (!f.isVolatile() && !f.isFinal()) { System.err.println(f.getReference()); } } } } } }
protected List<IField> findDeclaredField(Atom name) { List<IField> result = new ArrayList<>(1); if (instanceFields != null) { for (IField instanceField : instanceFields) { if (instanceField.getName() == name) { result.add(instanceField); } } } if (staticFields != null) { for (IField staticField : staticFields) { if (staticField.getName() == name) { result.add(staticField); } } } return result; }
@Override public SinkSpec[] getSinkSpecs() { List<SinkSpec> specs = new ArrayList<>(); Collection<IMethod> methods = cha.getPossibleTargets(StringStuff.makeMethodReference(methodSignature)); for (IField field : fields) { if (!field.isFinal()) { for (IMethod method : methods) { specs.add(new StaticFieldSinkSpec(field, method)); } } } return specs.toArray(new SinkSpec[] {}); }
for (IField f : klass.getDeclaredInstanceFields()) { int tempValue = nextLocal++; SSAGetInstruction G = insts.GetInstruction(statements.size(), tempValue, 1, f.getReference()); statements.add(G); SSAPutInstruction P = insts.PutInstruction(statements.size(), retValue, tempValue, f.getReference()); statements.add(P);
public void visitPutInternal(int rval, int ref, boolean isStatic, FieldReference field) { if (DEBUG) { System.err.println("visitPut " + field); } // skip putfields of primitive type if (field.getFieldType().isPrimitiveType()) { return; } IField f = getClassHierarchy().resolveField(field); if (f == null) { if (DEBUG) { System.err.println("Could not resolve field " + field); } Warnings.add(FieldResolutionFailure.create(field)); return; } assert f.getFieldTypeReference().getName().equals(field.getFieldType().getName()) : "name clash of two fields with the same name but different type: " + f.getReference() + " <=> " + field; assert isStatic || !symbolTable.isStringConstant(ref) : "put to string constant shouldn't be allowed?"; if (isStatic) { processPutStatic(rval, field, f); } else { processPutField(rval, ref, f); } }
private Map<PointerKey, Object> computePointerKeys(IClass klass) { Map<PointerKey, Object> result = HashMapFactory.make(); if (klass.isArrayClass()) { ArrayClass a = (ArrayClass) klass; if (a.getElementClass() != null && a.getElementClass().isReferenceType()) { PointerKey p = pointerKeys.getPointerKeyForArrayContents(new ConcreteTypeKey(a)); result.put(p, p); } } else { for (IField f : klass.getAllFields()) { if (!f.getFieldTypeReference().isPrimitiveType()) { if (f.isStatic()) { PointerKey p = pointerKeys.getPointerKeyForStaticField(f); result.put(p, p); } else { PointerKey p = pointerKeys.getPointerKeyForInstanceField(new ConcreteTypeKey(klass), f); result.put(p, p); } } } } return result; }
assert(f.isStatic()) : "All fields of AndroidModelClass are expected to be static! " + f + " is not."; final TypeReference fdType = f.getReference().getFieldType(); final VariableKey subKey = new SSAValue.WeaklyNamedKey(fdType.getName(), "ctx" + fdType.getName().getClassName().toString()); instance = this.pm.getUnallocated(fdType, subKey); final SSAInstruction getInst = instructionFactory.GetInstruction(pc, instance, f.getReference()); this.body.addStatement(getInst); this.pm.setAllocation(instance, getInst);
@Override public boolean shouldRefine(IField field, PointerKey basePtr, PointerKey val, IFlowLabel label, StateMachine.State state) { if (field == null) { throw new IllegalArgumentException("null field"); } if (field == ArrayContents.v()) { return true; } else { final IClass declaringClass = field.getDeclaringClass(); final Matcher m = refinePattern.matcher(declaringClass.toString()); final boolean foundPattern = m.find(); recordDecision(declaringClass, foundPattern); return foundPattern; } }
@Override public String descString() { return field.getDeclaringClass().toString() + '.' + field.getName().toString(); }
protected List<IField> findDeclaredField(Atom name) { List<IField> result = new ArrayList<>(1); if (instanceFields != null) { for (IField instanceField : instanceFields) { if (instanceField.getName() == name) { result.add(instanceField); } } } if (staticFields != null) { for (IField staticField : staticFields) { if (staticField.getName() == name) { result.add(staticField); } } } return result; }
public IUnaryFlowFunction makeStaticFieldTaints( BasicBlockInContext<E> dest, SSAInstruction inst, final PairBasedFlowFunction<E> flowFunction) { final Set<DomainElement> elts = HashSetFactory.make(); for (CodeElement ce : getStaticFieldAccessCodeElts((SSAGetInstruction) inst)) { StaticFieldElement sfe = (StaticFieldElement) ce; IField field = pa.getClassHierarchy().resolveField(sfe.getRef()); if (field.isFinal()) { continue; } final StaticFieldFlow<E> taintSource = new StaticFieldFlow<>(dest, field, true); elts.add(new DomainElement(ce, taintSource)); } IUnaryFlowFunction newTaints = new ConstantFlowFunction<>(domain, elts); return compose(flowFunction, newTaints); }