@Override public void onInstruction(Instruction i) { //if (shouldVisit(i)) { if (i instanceof FieldInstruction) { registerCoupling(((FieldInstruction) i).getFieldType(constants())); } else if (i instanceof InvokeInstruction) { final InvokeInstruction ii = (InvokeInstruction) i; registerCoupling(ii.getReferenceType(constants())); Stream.of(ii.getArgumentTypes(constants())).forEach(a -> registerCoupling(a)); registerCoupling(ii.getReturnType(constants())); } /* else if (i instanceof TypedInstruction) { final Type ti = ((TypedInstruction) i).getType(constants()); if (!ti.getSignature().equals("<null object>")) { registerCoupling(ti); } }*/ //} }
/** * If this is a putfield or putstatic instruction, check to see if the field * is @NonNull, and treat it as dereferences. * * @param location * the Location of the instruction * @param vnaFrame * the ValueNumberFrame at the Location of the instruction * @param fact * the dataflow value to modify * @throws DataflowAnalysisException */ private void checkNonNullPutField(Location location, ValueNumberFrame vnaFrame, UnconditionalValueDerefSet fact) throws DataflowAnalysisException { INullnessAnnotationDatabase database = AnalysisContext.currentAnalysisContext().getNullnessAnnotationDatabase(); if (database == null) { return; } FieldInstruction fieldIns = (FieldInstruction) location.getHandle().getInstruction(); XField field = XFactory.createXField(fieldIns, methodGen.getConstantPool()); char firstChar = field.getSignature().charAt(0); if (firstChar != 'L' && firstChar != '[') return; NullnessAnnotation resolvedAnnotation = database.getResolvedAnnotation(field, true); if (resolvedAnnotation == NullnessAnnotation.NONNULL) { IsNullValueFrame invFrame = invDataflow.getFactAtLocation(location); if (!invFrame.isValid()) return; IsNullValue value = invFrame.getTopValue(); if (reportDereference(value)) { ValueNumber vn = vnaFrame.getTopValue(); fact.addDeref(vn, location); } } }
/** * Look up the field referenced by given FieldInstruction, returning it as * an {@link XField XField} object. * * @param fins * the FieldInstruction * @param cpg * the ConstantPoolGen used by the class containing the * instruction * @return an XField object representing the field, or null if no such field * could be found */ public static @CheckForNull XField findXField(FieldInstruction fins, @Nonnull ConstantPoolGen cpg) { String className = fins.getClassName(cpg); String fieldName = fins.getFieldName(cpg); String fieldSig = fins.getSignature(cpg); boolean isStatic = (fins.getOpcode() == Constants.GETSTATIC || fins.getOpcode() == Constants.PUTSTATIC); XField xfield = findXField(className, fieldName, fieldSig, isStatic); short opcode = fins.getOpcode(); if (xfield != null && xfield.isResolved() && xfield.isStatic() == (opcode == Constants.GETSTATIC || opcode == Constants.PUTSTATIC)) return xfield; else return null; }
private void modelFieldStore(Location location) throws DataflowAnalysisException { // Model field stores XField writtenField = XFactory.createXField((FieldInstruction) location.getHandle().getInstruction(), cpg); TypeQualifierAnnotation tqa = TypeQualifierApplications.getEffectiveTypeQualifierAnnotation(writtenField, typeQualifierValue); When when = (tqa != null) ? tqa.when : When.UNKNOWN; // The ValueNumberFrame *before* the FieldInstruction should // have the ValueNumber of the stored value on the top of the stack. ValueNumberFrame vnaFrameAtStore = vnaDataflow.getFactAtLocation(location); if (vnaFrameAtStore.isValid()) { ValueNumber vn = vnaFrameAtStore.getTopValue(); SourceSinkInfo sink = new SourceSinkInfo(SourceSinkType.FIELD_STORE, location, vn, when); registerSourceSink(sink); } }
/** * If this is a putfield or putstatic instruction, check to see if the field * is @NonNull, and treat it as dereferences. * * @param location * the Location of the instruction * @param vnaFrame * the ValueNumberFrame at the Location of the instruction * @param fact * the dataflow value to modify * @throws DataflowAnalysisException */ private void checkNonNullPutField(Location location, ValueNumberFrame vnaFrame, UnconditionalValueDerefSet fact) throws DataflowAnalysisException { INullnessAnnotationDatabase database = AnalysisContext.currentAnalysisContext().getNullnessAnnotationDatabase(); FieldInstruction fieldIns = (FieldInstruction) location.getHandle().getInstruction(); XField field = XFactory.createXField(fieldIns, methodGen.getConstantPool()); char firstChar = field.getSignature().charAt(0); if (firstChar != 'L' && firstChar != '[') return; NullnessAnnotation resolvedAnnotation = database.getResolvedAnnotation(field, true); if (resolvedAnnotation == NullnessAnnotation.NONNULL) { IsNullValueFrame invFrame = invDataflow.getFactAtLocation(location); if (!invFrame.isValid()) return; IsNullValue value = invFrame.getTopValue(); if (reportDereference(value)) { ValueNumber vn = vnaFrame.getTopValue(); fact.addDeref(vn, location); } } }
/** * Get a Variable representing the stack value which will either be stored * into or loaded from a field. * * @param fieldIns the FieldInstruction accessing the field * @param cpg the ConstantPoolGen for the method * @param frame the ValueNumberFrame containing the value to be stored * or the value loaded */ protected static Variable snarfFieldValue(FieldInstruction fieldIns, ConstantPoolGen cpg, ValueNumberFrame frame) throws DataflowAnalysisException { if (isLongOrDouble(fieldIns, cpg)) { int numSlots = frame.getNumSlots(); ValueNumber topValue = frame.getValue(numSlots - 1); ValueNumber nextValue = frame.getValue(numSlots - 2); return new LongOrDoubleLocalVariable(topValue, nextValue); } else { return new LocalVariable(frame.getTopValue()); } }
private void emitFieldInstruction(Element xml_inst, FieldInstruction inst) { Type type = inst.getFieldType(cpg); xml_inst.setAttribute("class-type", inst.getClassName(cpg)); xml_inst.setAttribute("type", type.toString()); String name = inst.getName(cpg); xml_inst.setAttribute("field", name); }
private void handleLoad(FieldInstruction obj) { consumeStack(obj); Type type = obj.getType(getCPG()); if (!type.getSignature().equals(STRING_SIGNATURE)) throw new IllegalArgumentException("type is not String: " + type); try { String className = obj.getClassName(getCPG()); String fieldName = obj.getName(getCPG()); Field field = Hierarchy.findField(className, fieldName); if (field != null) { // If the field is final, we'll assume that the String value // is static. if (field.isFinal() && field.isFinal()) { pushValue(staticStringTypeInstance); } else { pushValue(type); } return; } } catch (ClassNotFoundException ex) { lookupFailureCallback.reportMissingClass(ex); } pushValue(type); }
private void handleInstruction(InstructionHandle handle, BasicBlock basicBlock, FieldSet fact) { Instruction ins = handle.getInstruction(); short opcode = ins.getOpcode(); XField field; switch (opcode) { case Constants.GETFIELD: case Constants.GETSTATIC: field = lookupField(handle, (FieldInstruction) ins); if (field != null) { sawLoad(fact, field); } break; case Constants.PUTFIELD: case Constants.PUTSTATIC: field = lookupField(handle, (FieldInstruction) ins); if (field != null) { sawStore(fact, field); } break; case Constants.INVOKEINTERFACE: case Constants.INVOKESPECIAL: case Constants.INVOKESTATIC: case Constants.INVOKEVIRTUAL: // Assume that the called method assigns loads and stores all // possible fields fact.setBottom(); break; } }
private @CheckForNull XField lookupField(InstructionHandle handle, FieldInstruction fins) { XField field = instructionToFieldMap.get(handle); if (field == null) { field = Hierarchy.findXField(fins, getCPG()); instructionToFieldMap.put(handle, field); } return field; }
private void handleFieldStore(FieldInstruction ins) { try { // If the resource instance is stored in a field, then it escapes ResourceValueFrame frame = getFrame(); ResourceValue topValue = frame.getTopValue(); if (topValue.equals(ResourceValue.instance())) frame.setStatus(ResourceValueFrame.ESCAPED); } catch (DataflowAnalysisException e) { throw new InvalidBytecodeException("Stack underflow", e); } handleNormalInstruction(ins); }
public static XField createXField(FieldInstruction fieldInstruction, ConstantPoolGen cpg) { String className = fieldInstruction.getClassName(cpg); String fieldName = fieldInstruction.getName(cpg); String fieldSig = fieldInstruction.getSignature(cpg); int opcode = fieldInstruction.getOpcode(); return createXField(className, fieldName, fieldSig, opcode == Constants.GETSTATIC || opcode == Constants.PUTSTATIC); }
private void registerFieldLoadSource(Location location) throws DataflowAnalysisException { XField loadedField = XFactory.createXField((FieldInstruction) location.getHandle().getInstruction(), cpg); if (loadedField.isResolved()) { TypeQualifierAnnotation tqa = TypeQualifierApplications.getEffectiveTypeQualifierAnnotation(loadedField, typeQualifierValue); When when = (tqa != null) ? tqa.when : When.UNKNOWN; registerTopOfStackSource(SourceSinkType.FIELD_LOAD, location, when, false, null); } }
/** * Get a Variable representing the stack value which will either be stored * into or loaded from a field. * * @param fieldIns * the FieldInstruction accessing the field * @param cpg * the ConstantPoolGen for the method * @param frame * the ValueNumberFrame containing the value to be stored or the * value loaded */ protected static Variable snarfFieldValue(FieldInstruction fieldIns, ConstantPoolGen cpg, ValueNumberFrame frame) throws DataflowAnalysisException { if (isLongOrDouble(fieldIns, cpg)) { int numSlots = frame.getNumSlots(); ValueNumber topValue = frame.getValue(numSlots - 1); ValueNumber nextValue = frame.getValue(numSlots - 2); return new LongOrDoubleLocalVariable(topValue, nextValue); } else { return new LocalVariable(frame.getTopValue()); } }
public void visitFieldInstruction( FieldInstruction i ) { short opcode = i.getOpcode(); String class_name = i.getClassName(_cp); String field_name = i.getFieldName(_cp); Type type = i.getFieldType(_cp); _out.println("il.append(_factory.createFieldAccess(\"" + class_name + "\", \"" + field_name + "\", " + BCELifier.printType(type) + ", " + "Constants." + Constants.OPCODE_NAMES[opcode].toUpperCase(Locale.ENGLISH) + "));"); }
protected FieldReference( FieldInstruction aInstruction, ConstantPoolGen aPoolGen) { super(aInstruction, aPoolGen); }
/** * Get FieldDescriptor describing the field accessed by given * FieldInstruction. * * @param fins * a FieldInstruction * @param cpg * ConstantPoolGen for the method containing the FieldInstruction * @return FieldDescriptor describing the field accessed by given * FieldInstruction */ public static FieldDescriptor getAccessedFieldDescriptor(FieldInstruction fins, ConstantPoolGen cpg) { String className = fins.getClassName(cpg); String fieldName = fins.getName(cpg); String fieldSig = fins.getSignature(cpg); boolean isStatic = (fins.getOpcode() == Constants.GETSTATIC || fins.getOpcode() == Constants.PUTSTATIC); return DescriptorFactory.instance().getFieldDescriptor(className, fieldName, fieldSig, isStatic); }
/** * Is the given instruction a read of a field? * * @param ins * the Instruction to check * @param cpg * ConstantPoolGen of the method containing the instruction * @return the Field if the instruction is a read of a field, null otherwise */ public static FieldAnnotation isRead(Instruction ins, ConstantPoolGen cpg) { if (ins instanceof GETFIELD || ins instanceof GETSTATIC) { FieldInstruction fins = (FieldInstruction) ins; String className = fins.getClassName(cpg); return new FieldAnnotation(className, fins.getName(cpg), fins.getSignature(cpg), fins instanceof GETSTATIC); } else return null; }
/** * Is the instruction a write of a field? * * @param ins * the Instruction to check * @param cpg * ConstantPoolGen of the method containing the instruction * @return the Field if instruction is a write of a field, null otherwise */ public static FieldAnnotation isWrite(Instruction ins, ConstantPoolGen cpg) { if (ins instanceof PUTFIELD || ins instanceof PUTSTATIC) { FieldInstruction fins = (FieldInstruction) ins; String className = fins.getClassName(cpg); return new FieldAnnotation(className, fins.getName(cpg), fins.getSignature(cpg), fins instanceof PUTSTATIC); } else return null; }
/** * Return whether the given FieldInstruction accesses a long or double field. * * @param fieldIns the FieldInstruction * @param cpg the ConstantPoolGen for the method */ protected static boolean isLongOrDouble(FieldInstruction fieldIns, ConstantPoolGen cpg) { Type type = fieldIns.getFieldType(cpg); int code = type.getType(); return code == T_LONG || code == T_DOUBLE; }
/** * Return whether the given FieldInstruction accesses a long or double * field. * * @param fieldIns * the FieldInstruction * @param cpg * the ConstantPoolGen for the method */ protected static boolean isLongOrDouble(FieldInstruction fieldIns, ConstantPoolGen cpg) { Type type = fieldIns.getFieldType(cpg); int code = type.getType(); return code == T_LONG || code == T_DOUBLE; }