Search in sources :

Example 1 with NeverNullArgAnalyzerAdapter

use of edu.columbia.cs.psl.phosphor.instrumenter.analyzer.NeverNullArgAnalyzerAdapter in project phosphor by gmu-swe.

the class TaintTrackingClassVisitor method generateNativeWrapper.

private void generateNativeWrapper(MethodNode m, String methodNameToCall, boolean skipUnboxing) {
    String[] exceptions = new String[m.exceptions.size()];
    exceptions = (String[]) m.exceptions.toArray(exceptions);
    Type[] argTypes = Type.getArgumentTypes(m.desc);
    boolean isPreAllocReturnType = TaintUtils.isPreAllocReturnType(m.desc);
    String newDesc = "(";
    LinkedList<LocalVariableNode> lvsToVisit = new LinkedList<LocalVariableNode>();
    LabelNode start = new LabelNode(new Label());
    LabelNode end = new LabelNode(new Label());
    for (Type t : argTypes) {
        if (t.getSort() == Type.ARRAY) {
            if (t.getElementType().getSort() != Type.OBJECT && t.getDimensions() == 1) {
                newDesc += TaintUtils.getShadowTaintType(t.getDescriptor());
            }
        } else if (t.getSort() != Type.OBJECT) {
            newDesc += Configuration.TAINT_TAG_DESC;
        }
        if (t.getSort() == Type.ARRAY && t.getElementType().getSort() != Type.OBJECT && t.getDimensions() > 1)
            newDesc += MultiDTaintedArray.getTypeForType(t).getDescriptor();
        else
            newDesc += t.getDescriptor();
    }
    Type origReturn = Type.getReturnType(m.desc);
    Type newReturn = TaintUtils.getContainerReturnType(origReturn);
    if (Configuration.IMPLICIT_TRACKING)
        newDesc += Type.getDescriptor(ControlTaintTagStack.class);
    if (m.name.equals("<init>"))
        newDesc += Type.getDescriptor(TaintSentinel.class);
    if (isPreAllocReturnType)
        newDesc += newReturn.getDescriptor();
    newDesc += ")" + newReturn.getDescriptor();
    MethodVisitor mv;
    if (m.name.equals("<init>")) {
        mv = super.visitMethod(m.access & ~Opcodes.ACC_NATIVE, m.name, newDesc, m.signature, exceptions);
    } else
        mv = super.visitMethod(m.access & ~Opcodes.ACC_NATIVE, m.name + TaintUtils.METHOD_SUFFIX + (skipUnboxing ? "$$NOUNBOX" : ""), newDesc, m.signature, exceptions);
    NeverNullArgAnalyzerAdapter an = new NeverNullArgAnalyzerAdapter(className, m.access, m.name, newDesc, mv);
    MethodVisitor soc = new SpecialOpcodeRemovingMV(an, false, className, false);
    LocalVariableManager lvs = new LocalVariableManager(m.access, newDesc, soc, an, mv, generateExtraLVDebug);
    lvs.setPrimitiveArrayAnalyzer(new PrimitiveArrayAnalyzer(newReturn));
    GeneratorAdapter ga = new GeneratorAdapter(lvs, m.access, m.name + TaintUtils.METHOD_SUFFIX, newDesc);
    if (isInterface) {
        ga.visitEnd();
        return;
    }
    ga.visitCode();
    ga.visitLabel(start.getLabel());
    String descToCall = m.desc;
    boolean isUntaggedCall = false;
    if (methodNameToCall.contains("$$PHOSPHORUNTAGGED")) {
        descToCall = TaintUtils.remapMethodDescForUninst(descToCall);
        isUntaggedCall = true;
    }
    int idx = 0;
    if ((m.access & Opcodes.ACC_STATIC) == 0) {
        ga.visitVarInsn(Opcodes.ALOAD, 0);
        lvsToVisit.add(new LocalVariableNode("this", "L" + className + ";", null, start, end, idx));
        idx++;
    }
    for (Type t : argTypes) {
        if (t.getSort() == Type.ARRAY) {
            if (t.getElementType().getSort() != Type.OBJECT && t.getDimensions() == 1) {
                lvsToVisit.add(new LocalVariableNode("phosphorNativeWrapArg" + idx, TaintUtils.getShadowTaintType(t.getDescriptor()), null, start, end, idx));
                idx++;
            }
        } else if (t.getSort() != Type.OBJECT) {
            lvsToVisit.add(new LocalVariableNode("phosphorNativeWrapArg" + idx, Configuration.TAINT_TAG_DESC, null, start, end, idx));
            idx++;
        }
        ga.visitVarInsn(t.getOpcode(Opcodes.ILOAD), idx);
        lvsToVisit.add(new LocalVariableNode("phosphorNativeWrapArg" + idx, t.getDescriptor(), null, start, end, idx));
        if (!skipUnboxing) {
            if (t.getDescriptor().equals("[Lsun/security/pkcs11/wrapper/CK_ATTRIBUTE;")) {
                ga.visitMethodInsn(Opcodes.INVOKESTATIC, Type.getInternalName(MultiDTaintedArray.class), "unboxCK_ATTRIBUTE", "([Lsun/security/pkcs11/wrapper/CK_ATTRIBUTE;)[Lsun/security/pkcs11/wrapper/CK_ATTRIBUTE;", false);
            } else if (t.getDescriptor().equals("Ljava/lang/Object;") || (t.getSort() == Type.ARRAY && t.getElementType().getDescriptor().equals("Ljava/lang/Object;"))) {
                // Need to make sure that it's not a boxed primitive array
                ga.visitInsn(Opcodes.DUP);
                ga.visitInsn(Opcodes.DUP);
                Label isOK = new Label();
                ga.visitTypeInsn(Opcodes.INSTANCEOF, "[" + Type.getDescriptor((!Configuration.MULTI_TAINTING ? LazyArrayIntTags.class : LazyArrayObjTags.class)));
                ga.visitInsn(Opcodes.SWAP);
                ga.visitTypeInsn(Opcodes.INSTANCEOF, Type.getInternalName((!Configuration.MULTI_TAINTING ? LazyArrayIntTags.class : LazyArrayObjTags.class)));
                ga.visitInsn(Opcodes.IOR);
                ga.visitJumpInsn(Opcodes.IFEQ, isOK);
                if (isUntaggedCall)
                    ga.visitMethodInsn(Opcodes.INVOKESTATIC, Type.getInternalName(MultiDTaintedArray.class), "unbox1D", "(Ljava/lang/Object;)Ljava/lang/Object;", false);
                else {
                    if (className.equals("sun/misc/Unsafe"))
                        ga.visitMethodInsn(Opcodes.INVOKESTATIC, Type.getInternalName((Configuration.MULTI_TAINTING ? MultiDTaintedArrayWithObjTag.class : MultiDTaintedArrayWithIntTag.class)), "unboxRawOnly1D", "(Ljava/lang/Object;)Ljava/lang/Object;", false);
                    else
                        ga.visitMethodInsn(Opcodes.INVOKESTATIC, Type.getInternalName((Configuration.MULTI_TAINTING ? MultiDTaintedArrayWithObjTag.class : MultiDTaintedArrayWithIntTag.class)), "unboxRaw", "(Ljava/lang/Object;)Ljava/lang/Object;", false);
                }
                if (t.getSort() == Type.ARRAY)
                    ga.visitTypeInsn(Opcodes.CHECKCAST, t.getInternalName());
                FrameNode fn = TaintAdapter.getCurrentFrameNode(an);
                ga.visitLabel(isOK);
                TaintAdapter.acceptFn(fn, lvs);
            } else if (!isUntaggedCall && t.getSort() == Type.ARRAY && t.getDimensions() > 1 && t.getElementType().getSort() != Type.OBJECT) {
                // Need to unbox it!!
                ga.visitMethodInsn(Opcodes.INVOKESTATIC, Type.getInternalName((Configuration.MULTI_TAINTING ? MultiDTaintedArrayWithObjTag.class : MultiDTaintedArrayWithIntTag.class)), "unboxRaw", "(Ljava/lang/Object;)Ljava/lang/Object;", false);
                ga.visitTypeInsn(Opcodes.CHECKCAST, t.getInternalName());
            }
        }
        idx += t.getSize();
    }
    int opcode;
    if ((m.access & Opcodes.ACC_STATIC) == 0) {
        opcode = Opcodes.INVOKESPECIAL;
    } else
        opcode = Opcodes.INVOKESTATIC;
    if (m.name.equals("<init>") && methodNameToCall.contains("$$PHOSPHORUNTAGGED")) {
        // call with uninst sentinel
        descToCall = descToCall.substring(0, descToCall.indexOf(')')) + Type.getDescriptor(UninstrumentedTaintSentinel.class) + ")" + descToCall.substring(descToCall.indexOf(')') + 1);
        ga.visitInsn(Opcodes.ACONST_NULL);
        ga.visitMethodInsn(opcode, className, m.name, descToCall, false);
    } else
        ga.visitMethodInsn(opcode, className, methodNameToCall, descToCall, false);
    if (origReturn != newReturn) {
        if (origReturn.getSort() == Type.ARRAY) {
            if (origReturn.getDimensions() > 1) {
                // System.out.println(an.stack + " > " + newReturn);
                Label isOK = new Label();
                ga.visitInsn(Opcodes.DUP);
                ga.visitJumpInsn(Opcodes.IFNULL, isOK);
                ga.visitTypeInsn(Opcodes.CHECKCAST, "[Ljava/lang/Object;");
                // //	public static Object[] initWithEmptyTaints(Object[] ar, int componentType, int dims) {
                ga.visitIntInsn(Opcodes.BIPUSH, origReturn.getElementType().getSort());
                ga.visitIntInsn(Opcodes.BIPUSH, origReturn.getDimensions());
                ga.visitMethodInsn(Opcodes.INVOKESTATIC, Type.getInternalName((Configuration.MULTI_TAINTING ? MultiDTaintedArrayWithObjTag.class : MultiDTaintedArrayWithIntTag.class)), "initWithEmptyTaints", "([Ljava/lang/Object;II)Ljava/lang/Object;", false);
                FrameNode fn = TaintAdapter.getCurrentFrameNode(an);
                fn.stack.set(fn.stack.size() - 1, "java/lang/Object");
                ga.visitLabel(isOK);
                TaintAdapter.acceptFn(fn, lvs);
                ga.visitTypeInsn(Opcodes.CHECKCAST, newReturn.getDescriptor());
            } else {
                TaintAdapter.createNewTaintArray(origReturn.getDescriptor(), an, lvs, lvs);
                ga.visitInsn(Opcodes.SWAP);
            // //						ga.visitInsn(Opcodes.SWAP);
            // ga.visitTypeInsn(Opcodes.NEW, newReturn.getInternalName()); //T V N
            // ga.visitInsn(Opcodes.DUP_X2); //N T V N
            // ga.visitInsn(Opcodes.DUP_X2); //N N T V N
            // ga.visitInsn(Opcodes.POP); //N N T V
            // ga.visitMethodInsn(Opcodes.INVOKESPECIAL, newReturn.getInternalName(), "<init>", "([I" + origReturn.getDescriptor() + ")V");
            // int retIdx = lvs.getPreAllocedReturnTypeVar(newReturn);
            // an.visitVarInsn(Opcodes.ALOAD, retIdx);
            // ga.visitInsn(Opcodes.SWAP);
            // ga.visitFieldInsn(Opcodes.PUTFIELD, newReturn.getInternalName(), "val", origReturn.getDescriptor());
            // an.visitVarInsn(Opcodes.ALOAD, retIdx);
            // ga.visitInsn(Opcodes.SWAP);
            // ga.visitFieldInsn(Opcodes.PUTFIELD, newReturn.getInternalName(), "taint", Configuration.TAINT_TAG_ARRAYDESC);
            // an.visitVarInsn(Opcodes.ALOAD, retIdx);
            }
        } else {
            // TODO here's where we store to the pre-alloc'ed container
            if (origReturn.getSize() == 1) {
                int retIdx = lvs.getPreAllocedReturnTypeVar(newReturn);
                an.visitVarInsn(Opcodes.ALOAD, retIdx);
                ga.visitInsn(Opcodes.SWAP);
                ga.visitFieldInsn(Opcodes.PUTFIELD, newReturn.getInternalName(), "val", origReturn.getDescriptor());
                an.visitVarInsn(Opcodes.ALOAD, retIdx);
                Configuration.taintTagFactory.generateEmptyTaint(ga);
                Configuration.taintTagFactory.propogateTagNative(className, m.access, m.name, m.desc, mv);
                ga.visitFieldInsn(Opcodes.PUTFIELD, newReturn.getInternalName(), "taint", Configuration.TAINT_TAG_DESC);
                an.visitVarInsn(Opcodes.ALOAD, retIdx);
            } else {
                int retIdx = lvs.getPreAllocedReturnTypeVar(newReturn);
                an.visitVarInsn(Opcodes.ALOAD, retIdx);
                ga.visitInsn(Opcodes.DUP_X2);
                ga.visitInsn(Opcodes.POP);
                ga.visitFieldInsn(Opcodes.PUTFIELD, newReturn.getInternalName(), "val", origReturn.getDescriptor());
                an.visitVarInsn(Opcodes.ALOAD, retIdx);
                Configuration.taintTagFactory.generateEmptyTaint(ga);
                Configuration.taintTagFactory.propogateTagNative(className, m.access, m.name, m.desc, mv);
                ga.visitFieldInsn(Opcodes.PUTFIELD, newReturn.getInternalName(), "taint", Configuration.TAINT_TAG_DESC);
                an.visitVarInsn(Opcodes.ALOAD, retIdx);
            // ga.visitInsn(Opcodes.ARETURN);
            }
        // if (origReturn.getSize() == 1)
        // ga.visitInsn(Opcodes.SWAP);
        // else {
        // ga.visitInsn(Opcodes.DUP_X2);
        // ga.visitInsn(Opcodes.POP);
        // }
        // ga.visitMethodInsn(Opcodes.INVOKESTATIC, newReturn.getInternalName(), "valueOf", "(I" + origReturn.getDescriptor() + ")" + newReturn.getDescriptor());
        }
    } else if (origReturn.getSort() != Type.VOID && (origReturn.getDescriptor().equals("Ljava/lang/Object;") || origReturn.getDescriptor().equals("[Ljava/lang/Object;"))) {
        // Check to see if the top of the stack is a primitive array, adn if so, box it.
        if (!isUntaggedCall) {
            ga.visitMethodInsn(Opcodes.INVOKESTATIC, Type.getInternalName((Configuration.MULTI_TAINTING ? MultiDTaintedArrayWithObjTag.class : MultiDTaintedArrayWithIntTag.class)), "boxIfNecessary", "(Ljava/lang/Object;)Ljava/lang/Object;", false);
            if (origReturn.getSort() == Type.ARRAY)
                ga.visitTypeInsn(Opcodes.CHECKCAST, "[Ljava/lang/Object;");
        }
    }
    ga.visitLabel(end.getLabel());
    ga.returnValue();
    if (isPreAllocReturnType) {
        lvsToVisit.add(new LocalVariableNode("phosphorReturnHolder", newReturn.getDescriptor(), null, start, end, lvs.getPreAllocedReturnTypeVar(newReturn)));
    }
    for (LocalVariableNode n : lvsToVisit) n.accept(ga);
    ga.visitMaxs(0, 0);
    ga.visitEnd();
}
Also used : LabelNode(org.objectweb.asm.tree.LabelNode) MultiDTaintedArray(edu.columbia.cs.psl.phosphor.struct.multid.MultiDTaintedArray) MultiDTaintedArrayWithObjTag(edu.columbia.cs.psl.phosphor.struct.multid.MultiDTaintedArrayWithObjTag) FrameNode(org.objectweb.asm.tree.FrameNode) Label(org.objectweb.asm.Label) MultiDTaintedArrayWithIntTag(edu.columbia.cs.psl.phosphor.struct.multid.MultiDTaintedArrayWithIntTag) LocalVariableNode(org.objectweb.asm.tree.LocalVariableNode) LinkedList(java.util.LinkedList) MethodVisitor(org.objectweb.asm.MethodVisitor) Type(org.objectweb.asm.Type) LazyArrayObjTags(edu.columbia.cs.psl.phosphor.struct.LazyArrayObjTags) NeverNullArgAnalyzerAdapter(edu.columbia.cs.psl.phosphor.instrumenter.analyzer.NeverNullArgAnalyzerAdapter) GeneratorAdapter(org.objectweb.asm.commons.GeneratorAdapter) LazyArrayIntTags(edu.columbia.cs.psl.phosphor.struct.LazyArrayIntTags)

Example 2 with NeverNullArgAnalyzerAdapter

use of edu.columbia.cs.psl.phosphor.instrumenter.analyzer.NeverNullArgAnalyzerAdapter in project phosphor by gmu-swe.

the class TaintLoadCoercer method main.

public static void main(String[] args) throws Throwable {
    Configuration.IMPLICIT_TRACKING = true;
    Configuration.MULTI_TAINTING = true;
    // Configuration.IMPLICIT_LIGHT_TRACKING = true;
    // Configuration.ARRAY_LENGTH_TRACKING = true;
    Configuration.ARRAY_INDEX_TRACKING = true;
    // Configuration.ANNOTATE_LOOPS = true;
    // Instrumenter.instrumentClass("asdf", new FileInputStream("z.class"), false);
    ClassReader cr = new ClassReader(new FileInputStream("z.class"));
    // ClassReader cr = new ClassReader(new FileInputStream("target/classes/VarInLoop.class"));
    final String className = cr.getClassName();
    PrintWriter pw = new PrintWriter("z.txt");
    TraceClassVisitor tcv = new TraceClassVisitor(null, new PhosphorTextifier(), pw);
    ClassWriter cw1 = new ClassWriter(ClassWriter.COMPUTE_FRAMES) {

        @Override
        protected String getCommonSuperClass(String arg0, String arg1) {
            try {
                return super.getCommonSuperClass(arg0, arg1);
            } catch (Throwable t) {
                return "java/lang/Object";
            }
        }
    };
    cr.accept(new ClassVisitor(Opcodes.ASM5, cw1) {

        @Override
        public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
            MethodVisitor mv = super.visitMethod(access, name, desc, signature, exceptions);
            mv = new JSRInlinerAdapter(mv, access, name, desc, signature, exceptions);
            return mv;
        }
    }, ClassReader.EXPAND_FRAMES);
    cr = new ClassReader(cw1.toByteArray());
    ClassVisitor cv = new ClassVisitor(Opcodes.ASM5, tcv) {

        String className;

        @Override
        public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {
            super.visit(version, access, name, signature, superName, interfaces);
            this.className = name;
        }

        HashSet<FieldNode> fields = new HashSet<FieldNode>();

        @Override
        public FieldVisitor visitField(int access, String name, String desc, String signature, Object value) {
            fields.add(new FieldNode(access, name, desc, signature, value));
            return super.visitField(access, name, desc, signature, value);
        }

        @Override
        public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
            // TODO Auto-generated method stub
            MethodVisitor mv = super.visitMethod(access, name, desc, signature, exceptions);
            mv = new MethodVisitor(Opcodes.ASM5, mv) {

                @Override
                public void visitInsn(int opcode) {
                    super.visitInsn(opcode);
                }
            };
            // mv = new SpecialOpcodeRemovingMV(mv,false,className,false);
            // NeverNullArgAnalyzerAdapter analyzer = new NeverNullArgAnalyzerAdapter(className, access, className, desc, mv);
            mv = new TaintLoadCoercer(className, access, name, desc, signature, exceptions, mv, true);
            // LocalVariableManager lvs = new LocalVariableManager(access, desc, mv, analyzer, mv, false);
            // mv = lvs;
            PrimitiveArrayAnalyzer paa = new PrimitiveArrayAnalyzer(className, access, name, desc, signature, exceptions, mv);
            NeverNullArgAnalyzerAdapter an = new NeverNullArgAnalyzerAdapter(className, access, name, desc, paa);
            paa.setAnalyzer(an);
            // ((PrimitiveArrayAnalyzer) mv).setAnalyzer(an);
            mv = an;
            return mv;
        }
    };
    cr.accept(cv, ClassReader.EXPAND_FRAMES);
    pw.flush();
}
Also used : FieldNode(org.objectweb.asm.tree.FieldNode) ClassVisitor(org.objectweb.asm.ClassVisitor) TraceClassVisitor(org.objectweb.asm.util.TraceClassVisitor) FileInputStream(java.io.FileInputStream) ClassWriter(org.objectweb.asm.ClassWriter) JSRInlinerAdapter(org.objectweb.asm.commons.JSRInlinerAdapter) MethodVisitor(org.objectweb.asm.MethodVisitor) TraceClassVisitor(org.objectweb.asm.util.TraceClassVisitor) NeverNullArgAnalyzerAdapter(edu.columbia.cs.psl.phosphor.instrumenter.analyzer.NeverNullArgAnalyzerAdapter) ClassReader(org.objectweb.asm.ClassReader) PrintWriter(java.io.PrintWriter) HashSet(java.util.HashSet)

Example 3 with NeverNullArgAnalyzerAdapter

use of edu.columbia.cs.psl.phosphor.instrumenter.analyzer.NeverNullArgAnalyzerAdapter in project phosphor by gmu-swe.

the class TaintTrackingClassVisitor method visitEnd.

@Override
public void visitEnd() {
    if ((isEnum || className.equals("java/lang/Enum")) && Configuration.WITH_ENUM_BY_VAL) {
        MethodVisitor mv = super.visitMethod(Opcodes.ACC_PUBLIC, "clone", "()Ljava/lang/Object;", null, new String[] { "java/lang/CloneNotSupportedException" });
        mv.visitCode();
        mv.visitVarInsn(Opcodes.ALOAD, 0);
        mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Object", "clone", "()Ljava/lang/Object;", false);
        mv.visitInsn(Opcodes.ARETURN);
        mv.visitEnd();
        mv.visitMaxs(0, 0);
    }
    boolean goLightOnGeneratedStuff = className.equals("java/lang/Byte");
    // }
    if (!hasSerialUID && !isInterface && !goLightOnGeneratedStuff) {
        if (!Configuration.MULTI_TAINTING)
            super.visitField(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, "serialVersionUIDPHOSPHOR_TAG", Configuration.TAINT_TAG_DESC, null, 0);
        else
            super.visitField(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, "serialVersionUIDPHOSPHOR_TAG", Configuration.TAINT_TAG_DESC, null, null);
    }
    // Add a field to track the instance's taint
    if (addTaintField && !goLightOnGeneratedStuff) {
        if (!Configuration.MULTI_TAINTING)
            super.visitField(Opcodes.ACC_PUBLIC, TaintUtils.TAINT_FIELD, "I", null, 0);
        else
            super.visitField(Opcodes.ACC_PUBLIC, TaintUtils.TAINT_FIELD, TaintAdapter.getTagType(className).getDescriptor(), null, null);
    // if(GEN_HAS_TAINTS_METHOD){
    // super.visitField(Opcodes.ACC_PUBLIC, TaintUtils.HAS_TAINT_FIELD, "Z", null, 0);
    // super.visitField(Opcodes.ACC_PUBLIC, TaintUtils.IS_TAINT_SEATCHING_FIELD, "Z", null, 0);
    // }
    }
    if (this.className.equals("java/lang/reflect/Method")) {
        super.visitField(Opcodes.ACC_PUBLIC, TaintUtils.TAINT_FIELD + "marked", "Z", null, 0);
        super.visitField(Opcodes.ACC_PUBLIC, TaintUtils.TAINT_FIELD + "method", "Ljava/lang/reflect/Method;", null, 0);
    } else if (this.className.equals("java/lang/Class")) {
        super.visitField(Opcodes.ACC_PUBLIC, TaintUtils.TAINT_FIELD + "marked", "Z", null, 0);
        super.visitField(Opcodes.ACC_PUBLIC, TaintUtils.TAINT_FIELD + "class", "Ljava/lang/Class;", null, 0);
    }
    for (FieldNode fn : extraFieldsToVisit) {
        if (className.equals("java/lang/Byte") && !fn.name.startsWith("value"))
            continue;
        if (isNormalClass) {
            fn.access = fn.access & ~Opcodes.ACC_FINAL;
            fn.access = fn.access & ~Opcodes.ACC_PRIVATE;
            fn.access = fn.access & ~Opcodes.ACC_PROTECTED;
            fn.access = fn.access | Opcodes.ACC_PUBLIC;
        }
        if ((fn.access & Opcodes.ACC_STATIC) != 0) {
            if (fn.desc.equals("I"))
                super.visitField(fn.access, fn.name, fn.desc, fn.signature, 0);
            else
                super.visitField(fn.access, fn.name, fn.desc, fn.signature, null);
        } else
            super.visitField(fn.access, fn.name, fn.desc, fn.signature, null);
    }
    if (FIELDS_ONLY)
        return;
    if ((isAbstractClass || isInterface) && implementsComparable && !goLightOnGeneratedStuff) {
        // Need to add this to interfaces so that we can call it on the interface
        if (Configuration.IMPLICIT_TRACKING)
            super.visitMethod(Opcodes.ACC_PUBLIC | Opcodes.ACC_ABSTRACT, "compareTo$$PHOSPHORTAGGED", "(Ljava/lang/Object;" + Type.getDescriptor(ControlTaintTagStack.class) + Configuration.TAINTED_INT_DESC + ")" + Configuration.TAINTED_INT_DESC, null, null);
        else
            super.visitMethod(Opcodes.ACC_PUBLIC | Opcodes.ACC_ABSTRACT, "compareTo$$PHOSPHORTAGGED", "(Ljava/lang/Object;" + Configuration.TAINTED_INT_DESC + ")" + Configuration.TAINTED_INT_DESC, null, null);
        if (Configuration.GENERATE_UNINST_STUBS) {
            super.visitMethod(Opcodes.ACC_PUBLIC | Opcodes.ACC_ABSTRACT, "compareTo$$PHOSPHORUNTAGGED", "(Ljava/lang/Object;)I", null, null);
        }
    }
    if (generateEquals && !goLightOnGeneratedStuff) {
        superMethodsToOverride.remove("equals(Ljava/lang/Object;)Z");
        methodsToAddWrappersFor.add(new MethodNode(Opcodes.ACC_PUBLIC | Opcodes.ACC_NATIVE, "equals", "(Ljava/lang/Object;)Z", null, null));
        MethodVisitor mv;
        mv = super.visitMethod(Opcodes.ACC_PUBLIC, "equals", "(Ljava/lang/Object;)Z", null, null);
        mv.visitCode();
        Label start = new Label();
        Label end = new Label();
        mv.visitLabel(start);
        mv.visitVarInsn(Opcodes.ALOAD, 0);
        mv.visitVarInsn(Opcodes.ALOAD, 1);
        mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Object", "equals", "(Ljava/lang/Object;)Z", false);
        mv.visitLabel(end);
        mv.visitInsn(Opcodes.IRETURN);
        mv.visitLocalVariable("this", "L" + className + ";", null, start, end, 0);
        mv.visitLocalVariable("other", "Ljava/lang/Object;", null, start, end, 1);
        mv.visitMaxs(0, 0);
        mv.visitEnd();
    }
    if (generateHashCode && !goLightOnGeneratedStuff) {
        superMethodsToOverride.remove("hashCode()I");
        methodsToAddWrappersFor.add(new MethodNode(Opcodes.ACC_PUBLIC | Opcodes.ACC_NATIVE, "hashCode", "()I", null, null));
        MethodVisitor mv;
        mv = super.visitMethod(Opcodes.ACC_PUBLIC, "hashCode", "()I", null, null);
        mv.visitCode();
        Label start = new Label();
        Label end = new Label();
        mv.visitLabel(start);
        mv.visitVarInsn(Opcodes.ALOAD, 0);
        mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Object", "hashCode", "()I", false);
        mv.visitLabel(end);
        mv.visitInsn(Opcodes.IRETURN);
        mv.visitLocalVariable("this", "L" + className + ";", null, start, end, 0);
        mv.visitMaxs(0, 0);
        mv.visitEnd();
    }
    if (addTaintMethod) {
        if (isInterface) {
            super.visitMethod(Opcodes.ACC_PUBLIC | Opcodes.ACC_ABSTRACT, "get" + TaintUtils.TAINT_FIELD, "()" + (Configuration.MULTI_TAINTING ? "Ljava/lang/Object;" : "I"), null, null);
            if (GEN_HAS_TAINTS_METHOD)
                super.visitMethod(Opcodes.ACC_PUBLIC | Opcodes.ACC_ABSTRACT, "hasAnyTaints", "()Z", null, null);
            super.visitMethod(Opcodes.ACC_PUBLIC | Opcodes.ACC_ABSTRACT, "set" + TaintUtils.TAINT_FIELD, "(" + (Configuration.MULTI_TAINTING ? "Ljava/lang/Object;" : "I") + ")V", null, null);
        } else {
            MethodVisitor mv;
            if (!Configuration.MULTI_TAINTING) {
                mv = super.visitMethod(Opcodes.ACC_PUBLIC, "get" + TaintUtils.TAINT_FIELD, "()" + (Configuration.MULTI_TAINTING ? "Ljava/lang/Object;" : "I"), null, null);
                mv.visitCode();
                mv.visitVarInsn(Opcodes.ALOAD, 0);
                mv.visitFieldInsn(Opcodes.GETFIELD, className, TaintUtils.TAINT_FIELD, Configuration.TAINT_TAG_DESC);
                mv.visitInsn(Opcodes.IRETURN);
                mv.visitMaxs(0, 0);
                mv.visitEnd();
                mv = super.visitMethod(Opcodes.ACC_PUBLIC, "set" + TaintUtils.TAINT_FIELD, "(" + (Configuration.MULTI_TAINTING ? "Ljava/lang/Object;" : "I") + ")V", null, null);
                mv.visitCode();
                Configuration.taintTagFactory.generateSetTag(mv, className);
                if (className.equals("java/lang/String")) {
                    // Also overwrite the taint tag of all of the chars behind this string
                    Type taintType = MultiDTaintedArray.getTypeForType(Type.getType(char[].class));
                    mv.visitVarInsn(Opcodes.ALOAD, 0);
                    mv.visitInsn(Opcodes.DUP);
                    mv.visitFieldInsn(Opcodes.GETFIELD, className, "value", "[C");
                    // A
                    mv.visitTypeInsn(Opcodes.NEW, taintType.getInternalName());
                    // A T
                    mv.visitInsn(Opcodes.DUP_X1);
                    // T A T
                    mv.visitInsn(Opcodes.SWAP);
                    mv.visitMethodInsn(Opcodes.INVOKESPECIAL, taintType.getInternalName(), "<init>", "([C)V", false);
                    // T
                    mv.visitInsn(Opcodes.DUP_X1);
                    mv.visitFieldInsn(Opcodes.PUTFIELD, className, "value" + TaintUtils.TAINT_FIELD, taintType.getDescriptor());
                    mv.visitVarInsn(Opcodes.ILOAD, 1);
                    mv.visitMethodInsn(Opcodes.INVOKESTATIC, Configuration.STRING_SET_TAG_TAINT_CLASS, "setTaints", "(" + taintType.getDescriptor() + "I)V", false);
                // =======
                // mv.visitMethodInsn(Opcodes.INVOKESTATIC, Type.getInternalName(TaintChecker.class), "setTaints", "([II)V", false);
                } else if ((className.equals(TaintPassingMV.INTEGER_NAME) || className.equals(TaintPassingMV.LONG_NAME) || className.equals(TaintPassingMV.FLOAT_NAME) || className.equals(TaintPassingMV.DOUBLE_NAME))) {
                    mv.visitVarInsn(Opcodes.ALOAD, 0);
                    mv.visitVarInsn(Opcodes.ILOAD, 1);
                    mv.visitFieldInsn(Opcodes.PUTFIELD, className, "value" + TaintUtils.TAINT_FIELD, Configuration.TAINT_TAG_DESC);
                // For primitive types, also set the "value" field
                // >>>>>>> master
                }
                mv.visitInsn(Opcodes.RETURN);
                mv.visitMaxs(0, 0);
                mv.visitEnd();
            } else {
                mv = super.visitMethod(Opcodes.ACC_PUBLIC, "get" + TaintUtils.TAINT_FIELD, "()" + (Configuration.MULTI_TAINTING ? "Ljava/lang/Object;" : "I"), null, null);
                mv = new TaintTagFieldCastMV(mv);
                mv.visitCode();
                mv.visitVarInsn(Opcodes.ALOAD, 0);
                mv.visitFieldInsn(Opcodes.GETFIELD, className, TaintUtils.TAINT_FIELD, Configuration.TAINT_TAG_DESC);
                mv.visitInsn(Opcodes.ARETURN);
                mv.visitMaxs(0, 0);
                mv.visitEnd();
                mv = super.visitMethod(Opcodes.ACC_PUBLIC, "set" + TaintUtils.TAINT_FIELD, "(" + (Configuration.MULTI_TAINTING ? "Ljava/lang/Object;" : "I") + ")V", null, null);
                mv = new TaintTagFieldCastMV(mv);
                mv.visitCode();
                Configuration.taintTagFactory.generateSetTag(mv, className);
                if (className.equals("java/lang/String")) {
                    // Also overwrite the taint tag of all of the chars behind this string
                    Type taintType = MultiDTaintedArray.getTypeForType(Type.getType(char[].class));
                    mv.visitVarInsn(Opcodes.ALOAD, 0);
                    mv.visitInsn(Opcodes.DUP);
                    mv.visitFieldInsn(Opcodes.GETFIELD, className, "value", "[C");
                    // A
                    mv.visitTypeInsn(Opcodes.NEW, taintType.getInternalName());
                    // A T
                    mv.visitInsn(Opcodes.DUP_X1);
                    // T A T
                    mv.visitInsn(Opcodes.SWAP);
                    mv.visitMethodInsn(Opcodes.INVOKESPECIAL, taintType.getInternalName(), "<init>", "([C)V", false);
                    // T
                    mv.visitInsn(Opcodes.DUP_X1);
                    mv.visitFieldInsn(Opcodes.PUTFIELD, className, "value" + TaintUtils.TAINT_FIELD, taintType.getDescriptor());
                    mv.visitVarInsn(Opcodes.ALOAD, 1);
                    mv.visitMethodInsn(Opcodes.INVOKESTATIC, Configuration.STRING_SET_TAG_TAINT_CLASS, "setTaints", "(" + taintType.getDescriptor() + "Ljava/lang/Object;)V", false);
                } else if ((className.equals(TaintPassingMV.INTEGER_NAME) || className.equals(TaintPassingMV.LONG_NAME) || className.equals(TaintPassingMV.FLOAT_NAME) || className.equals(TaintPassingMV.DOUBLE_NAME))) {
                    // For primitive types, also set the "value" field
                    mv.visitVarInsn(Opcodes.ALOAD, 0);
                    mv.visitVarInsn(Opcodes.ALOAD, 1);
                    mv.visitFieldInsn(Opcodes.PUTFIELD, className, "value" + TaintUtils.TAINT_FIELD, Configuration.TAINT_TAG_DESC);
                }
                mv.visitInsn(Opcodes.RETURN);
                mv.visitMaxs(0, 0);
                mv.visitEnd();
            }
        // if (!this.isProxyClass && GEN_HAS_TAINTS_METHOD) {
        // mv = super.visitMethod(Opcodes.ACC_PUBLIC, "hasAnyTaints", "()Z", null, null);
        // mv.visitCode();
        // Label keepGoing1 = new Label();
        // mv.visitVarInsn(Opcodes.ALOAD, 0);
        // mv.visitFieldInsn(Opcodes.GETFIELD, className, TaintUtils.HAS_TAINT_FIELD, "Z");
        // mv.visitJumpInsn(Opcodes.IFEQ, keepGoing1);
        // mv.visitInsn(Opcodes.ICONST_1);
        // mv.visitInsn(Opcodes.IRETURN);
        // mv.visitLabel(keepGoing1);
        // //TODO if the istaitnsearchingfield is 1, then return 0.
        // mv.visitVarInsn(Opcodes.ALOAD, 0);
        // mv.visitFieldInsn(Opcodes.GETFIELD, className, TaintUtils.IS_TAINT_SEATCHING_FIELD, "Z");
        // Label keepGoing = new Label();
        // mv.visitJumpInsn(Opcodes.IFEQ, keepGoing);
        // mv.visitInsn(Opcodes.ICONST_0);
        // mv.visitInsn(Opcodes.IRETURN);
        // mv.visitLabel(keepGoing);
        // if (myFields.size() > 0) {
        // mv.visitVarInsn(Opcodes.ALOAD, 0);
        // mv.visitInsn(Opcodes.ICONST_1);
        // mv.visitFieldInsn(Opcodes.PUTFIELD, className, TaintUtils.IS_TAINT_SEATCHING_FIELD, "Z");
        // 
        // Label hasTaint = new Label();
        // for (FieldNode fn : myFields) {
        // Type fieldDesc = Type.getType(fn.desc);
        // if (TaintUtils.getShadowTaintType(fn.desc) != null) {
        // if (fieldDesc.getSort() == Type.ARRAY) {
        // mv.visitVarInsn(Opcodes.ALOAD, 0);
        // mv.visitFieldInsn(Opcodes.GETFIELD, className, fn.name + TaintUtils.TAINT_FIELD, TaintUtils.getShadowTaintType(fn.desc));
        // if (fieldDesc.getDimensions() == 1) {
        // mv.visitMethodInsn(Opcodes.INVOKESTATIC, Type.getInternalName(TaintUtils.class), "arrayHasTaints", "([I)Z",false);
        // } else if (fieldDesc.getDimensions() == 2) {
        // mv.visitMethodInsn(Opcodes.INVOKESTATIC, Type.getInternalName(TaintUtils.class), "arrayHasTaints", "([[I)Z",false);
        // } else if (fieldDesc.getDimensions() == 3) {
        // mv.visitMethodInsn(Opcodes.INVOKESTATIC, Type.getInternalName(TaintUtils.class), "arrayHasTaints", "([[[I)Z",false);
        // } else {
        // //bail and say that it has a taint i guess
        // mv.visitInsn(Opcodes.POP);
        // mv.visitInsn(Opcodes.ICONST_1);
        // }
        // mv.visitJumpInsn(Opcodes.IFNE, hasTaint);
        // } else {
        // mv.visitVarInsn(Opcodes.ALOAD, 0);
        // mv.visitFieldInsn(Opcodes.GETFIELD, className, fn.name + TaintUtils.TAINT_FIELD, "I");
        // mv.visitJumpInsn(Opcodes.IFNE, hasTaint);
        // }
        // } else if (!Instrumenter.isIgnoredClass(fieldDesc.getInternalName()) && GEN_HAS_TAINTS_METHOD) {
        // int op = Opcodes.INVOKEVIRTUAL;
        // if (Instrumenter.isInterface(fieldDesc.getInternalName()))
        // op = Opcodes.INVOKEINTERFACE;
        // mv.visitVarInsn(Opcodes.ALOAD, 0);
        // mv.visitFieldInsn(Opcodes.GETFIELD, className, fn.name, fn.desc);
        // mv.visitMethodInsn(op, fieldDesc.getInternalName(), "hasAnyTaints", "()Z",false);
        // mv.visitJumpInsn(Opcodes.IFNE, hasTaint);
        // } else {
        // //TODO XXX MUST FETCH THE TAINT SOMEHOW FOR IGNORED CLASSES FOR THIS TO BE SOUND
        // }
        // }
        // 
        // mv.visitVarInsn(Opcodes.ALOAD, 0);
        // mv.visitInsn(Opcodes.ICONST_0);
        // mv.visitFieldInsn(Opcodes.PUTFIELD, className, TaintUtils.IS_TAINT_SEATCHING_FIELD, "Z");
        // 
        // mv.visitInsn(Opcodes.ICONST_0);
        // mv.visitInsn(Opcodes.IRETURN);
        // 
        // mv.visitLabel(hasTaint);
        // mv.visitVarInsn(Opcodes.ALOAD, 0);
        // mv.visitInsn(Opcodes.ICONST_0);
        // mv.visitFieldInsn(Opcodes.PUTFIELD, className, TaintUtils.IS_TAINT_SEATCHING_FIELD, "Z");
        // 
        // mv.visitVarInsn(Opcodes.ALOAD, 0);
        // mv.visitInsn(Opcodes.ICONST_1);
        // mv.visitFieldInsn(Opcodes.PUTFIELD, className, TaintUtils.HAS_TAINT_FIELD, "Z");
        // mv.visitInsn(Opcodes.ICONST_1);
        // mv.visitInsn(Opcodes.IRETURN);
        // } else {
        // mv.visitInsn(Opcodes.ICONST_0);
        // mv.visitInsn(Opcodes.IRETURN);
        // }
        // mv.visitMaxs(0, 0);
        // mv.visitEnd();
        // }
        }
    }
    // generateStrLdcWrapper();
    if (!goLightOnGeneratedStuff)
        for (MethodNode m : methodsToAddWrappersFor) {
            if ((m.access & Opcodes.ACC_NATIVE) == 0) {
                if ((m.access & Opcodes.ACC_ABSTRACT) == 0) {
                    // not native
                    MethodNode fullMethod = forMore.get(m);
                    Type origReturn = Type.getReturnType(m.desc);
                    Type newReturn = TaintUtils.getContainerReturnType(origReturn);
                    boolean needToPrealloc = TaintUtils.isPreAllocReturnType(m.desc);
                    String[] exceptions = new String[m.exceptions.size()];
                    exceptions = (String[]) m.exceptions.toArray(exceptions);
                    MethodVisitor mv = super.visitMethod(m.access, m.name, m.desc, m.signature, exceptions);
                    mv = new TaintTagFieldCastMV(mv);
                    if (fullMethod != null) {
                        visitAnnotations(mv, fullMethod);
                    }
                    NeverNullArgAnalyzerAdapter an = new NeverNullArgAnalyzerAdapter(className, m.access, m.name, m.desc, mv);
                    MethodVisitor soc = new SpecialOpcodeRemovingMV(an, false, className, false);
                    LocalVariableManager lvs = new LocalVariableManager(m.access, m.desc, soc, an, mv, generateExtraLVDebug);
                    lvs.setPrimitiveArrayAnalyzer(new PrimitiveArrayAnalyzer(newReturn));
                    GeneratorAdapter ga = new GeneratorAdapter(lvs, m.access, m.name, m.desc);
                    Label startLabel = new Label();
                    ga.visitCode();
                    ga.visitLabel(startLabel);
                    ga.visitLineNumber(0, startLabel);
                    Type[] argTypes = Type.getArgumentTypes(m.desc);
                    int idx = 0;
                    if ((m.access & Opcodes.ACC_STATIC) == 0) {
                        ga.visitVarInsn(Opcodes.ALOAD, 0);
                        idx++;
                    }
                    String newDesc = "(";
                    for (Type t : argTypes) {
                        boolean loaded = false;
                        boolean needToBoxMultiD = false;
                        if (t.getSort() == Type.ARRAY) {
                            if (t.getElementType().getSort() != Type.OBJECT) {
                                if (t.getDimensions() == 1) {
                                    newDesc += TaintUtils.getShadowTaintType(t.getDescriptor());
                                    ga.visitVarInsn(Opcodes.ALOAD, idx);
                                    TaintAdapter.createNewTaintArray(t.getDescriptor(), an, lvs, lvs);
                                    loaded = true;
                                } else {
                                    newDesc += MultiDTaintedArray.getTypeForType(t).getDescriptor();
                                    needToBoxMultiD = true;
                                }
                            }
                        } else if (t.getSort() != Type.OBJECT) {
                            newDesc += Configuration.TAINT_TAG_DESC;
                            Configuration.taintTagFactory.generateEmptyTaint(ga);
                        }
                        if (!loaded)
                            ga.visitVarInsn(t.getOpcode(Opcodes.ILOAD), idx);
                        if (NATIVE_BOX_UNBOX && t.getSort() == Type.OBJECT && Instrumenter.isCollection(t.getInternalName())) {
                            // //  public final static ensureIsBoxed(Ljava/util/Collection;)Ljava/util/Collection;
                            ga.visitMethodInsn(Opcodes.INVOKESTATIC, Type.getInternalName(NativeHelper.class), "ensureIsBoxed" + (Configuration.MULTI_TAINTING ? "ObjTags" : ""), "(Ljava/util/Collection;)Ljava/util/Collection;", false);
                            ga.visitTypeInsn(Opcodes.CHECKCAST, t.getInternalName());
                        }
                        if (t.getDescriptor().endsWith("java/lang/Object;")) {
                            ga.visitMethodInsn(Opcodes.INVOKESTATIC, Type.getInternalName(MultiDTaintedArray.class), "boxIfNecessary", "(Ljava/lang/Object;)Ljava/lang/Object;", false);
                            ga.visitTypeInsn(Opcodes.CHECKCAST, t.getInternalName());
                        }
                        if (!needToBoxMultiD)
                            newDesc += t.getDescriptor();
                        else {
                            // Label isNull = new Label();
                            Label isDone = new Label();
                            ga.visitInsn(Opcodes.DUP);
                            ga.visitJumpInsn(Opcodes.IFNULL, isDone);
                            ga.visitIntInsn(Opcodes.BIPUSH, t.getElementType().getSort());
                            ga.visitIntInsn(Opcodes.BIPUSH, t.getDimensions());
                            ga.visitMethodInsn(Opcodes.INVOKESTATIC, Type.getInternalName((Configuration.MULTI_TAINTING ? MultiDTaintedArrayWithObjTag.class : MultiDTaintedArrayWithIntTag.class)), "initWithEmptyTaints", "([Ljava/lang/Object;II)Ljava/lang/Object;", false);
                            FrameNode fn = TaintAdapter.getCurrentFrameNode(an);
                            fn.stack.set(fn.stack.size() - 1, "java/lang/Object");
                            ga.visitLabel(isDone);
                            TaintAdapter.acceptFn(fn, lvs);
                            ga.visitTypeInsn(Opcodes.CHECKCAST, MultiDTaintedArray.getTypeForType(t).getDescriptor());
                        }
                        idx += t.getSize();
                    }
                    if (Configuration.IMPLICIT_TRACKING) {
                        newDesc += Type.getDescriptor(ControlTaintTagStack.class);
                        ga.visitTypeInsn(Opcodes.NEW, Type.getInternalName(ControlTaintTagStack.class));
                        ga.visitInsn(Opcodes.DUP);
                        ga.visitMethodInsn(Opcodes.INVOKESPECIAL, Type.getInternalName(ControlTaintTagStack.class), "<init>", "()V", false);
                    }
                    if (m.name.equals("<init>")) {
                        newDesc += Type.getDescriptor(TaintSentinel.class);
                        ga.visitInsn(Opcodes.ACONST_NULL);
                    }
                    if (needToPrealloc) {
                        newDesc += newReturn.getDescriptor();
                        an.visitVarInsn(Opcodes.ALOAD, lvs.getPreAllocedReturnTypeVar(newReturn));
                    }
                    newDesc += ")" + newReturn.getDescriptor();
                    int opcode;
                    if ((m.access & Opcodes.ACC_STATIC) == 0) {
                        opcode = Opcodes.INVOKESPECIAL;
                    } else
                        opcode = Opcodes.INVOKESTATIC;
                    if (m.name.equals("<init>")) {
                        ga.visitMethodInsn(Opcodes.INVOKESPECIAL, className, m.name, newDesc, false);
                    } else
                        ga.visitMethodInsn(opcode, className, m.name + TaintUtils.METHOD_SUFFIX, newDesc, false);
                    // unbox collections
                    idx = 0;
                    if ((m.access & Opcodes.ACC_STATIC) == 0) {
                        idx++;
                    }
                    for (Type t : argTypes) {
                        if (NATIVE_BOX_UNBOX && t.getSort() == Type.OBJECT && Instrumenter.isCollection(t.getInternalName())) {
                            // //  public final static ensureIsBoxed(Ljava/util/Collection;)Ljava/util/Collection;
                            ga.visitVarInsn(t.getOpcode(Opcodes.ILOAD), idx);
                            ga.visitMethodInsn(Opcodes.INVOKESTATIC, Type.getInternalName(NativeHelper.class), "ensureIsUnBoxed" + (Configuration.MULTI_TAINTING ? "ObjTags" : ""), "(Ljava/util/Collection;)Ljava/util/Collection;", false);
                            ga.visitInsn(Opcodes.POP);
                        }
                        idx += t.getSize();
                    }
                    if (origReturn != newReturn) {
                        String taintType = TaintUtils.getShadowTaintType(origReturn.getDescriptor());
                        if (taintType != null) {
                            // ga.visitInsn(Opcodes.SWAP);
                            if (origReturn.getSort() == Type.ARRAY) {
                                FrameNode fn2 = TaintAdapter.getCurrentFrameNode(an);
                                Label isNull = new Label();
                                ga.visitInsn(Opcodes.DUP);
                                Label isDone = new Label();
                                ga.visitJumpInsn(Opcodes.IFNULL, isNull);
                                ga.visitFieldInsn(Opcodes.GETFIELD, newReturn.getInternalName(), "val", origReturn.getDescriptor());
                                FrameNode fn = TaintAdapter.getCurrentFrameNode(an);
                                ga.visitJumpInsn(Opcodes.GOTO, isDone);
                                fn.type = Opcodes.F_NEW;
                                fn2.type = Opcodes.F_NEW;
                                ga.visitLabel(isNull);
                                TaintAdapter.acceptFn(fn2, ga);
                                ga.visitInsn(Opcodes.POP);
                                ga.visitInsn(Opcodes.ACONST_NULL);
                                ga.visitLabel(isDone);
                                TaintAdapter.acceptFn(fn, ga);
                            } else
                                ga.visitFieldInsn(Opcodes.GETFIELD, newReturn.getInternalName(), "val", origReturn.getDescriptor());
                        } else {
                            // Need to convert from [[WrapperForCArray to [[[C
                            Label isDone = new Label();
                            ga.visitInsn(Opcodes.DUP);
                            ga.visitJumpInsn(Opcodes.IFNULL, isDone);
                            ga.visitIntInsn(Opcodes.BIPUSH, origReturn.getElementType().getSort());
                            ga.visitIntInsn(Opcodes.BIPUSH, origReturn.getDimensions() - 1);
                            ga.visitMethodInsn(Opcodes.INVOKESTATIC, Type.getInternalName((Configuration.MULTI_TAINTING ? MultiDTaintedArrayWithObjTag.class : MultiDTaintedArrayWithIntTag.class)), "unboxVal", "(Ljava/lang/Object;II)Ljava/lang/Object;", false);
                            FrameNode fn = TaintAdapter.getCurrentFrameNode(an);
                            fn.stack.set(fn.stack.size() - 1, "java/lang/Object");
                            ga.visitLabel(isDone);
                            TaintAdapter.acceptFn(fn, lvs);
                            ga.visitTypeInsn(Opcodes.CHECKCAST, origReturn.getInternalName());
                        }
                    }
                    Label endLabel = new Label();
                    ga.visitLabel(endLabel);
                    ga.returnValue();
                    // int j = 0;
                    for (Object o : m.localVariables) {
                        LocalVariableNode n = (LocalVariableNode) o;
                        ga.visitLocalVariable(n.name, n.desc, n.signature, startLabel, endLabel, n.index);
                    }
                    if (m.name.equals("<init>")) {
                    }
                    ga.visitMaxs(0, 0);
                    ga.visitEnd();
                } else {
                    String[] exceptions = new String[m.exceptions.size()];
                    exceptions = (String[]) m.exceptions.toArray(exceptions);
                    MethodNode fullMethod = forMore.get(m);
                    MethodVisitor mv = super.visitMethod(m.access, m.name, m.desc, m.signature, exceptions);
                    if (fullMethod.annotationDefault != null) {
                        AnnotationVisitor av = mv.visitAnnotationDefault();
                        acceptAnnotationRaw(av, null, fullMethod.annotationDefault);
                        av.visitEnd();
                    }
                    m.accept(mv);
                }
            } else {
                // generate wrapper for native method - a native wrapper
                generateNativeWrapper(m, m.name, false);
                if (className.equals("sun/misc/Unsafe"))
                    generateNativeWrapper(m, m.name, true);
            }
        }
    superMethodsToOverride.remove("wait(JI)V");
    superMethodsToOverride.remove("wait(J)V");
    superMethodsToOverride.remove("wait()V");
    superMethodsToOverride.remove("notify()V");
    superMethodsToOverride.remove("notifyAll()V");
    for (Method m : superMethodsToOverride.values()) {
        int acc = Opcodes.ACC_PUBLIC;
        if (Modifier.isProtected(m.getModifiers()) && isInterface)
            continue;
        else if (Modifier.isPrivate(m.getModifiers()))
            continue;
        if (Modifier.isStatic(m.getModifiers()))
            acc = acc | Opcodes.ACC_STATIC;
        if (isInterface)
            acc = acc | Opcodes.ACC_ABSTRACT;
        else
            acc = acc & ~Opcodes.ACC_ABSTRACT;
        MethodNode mn = new MethodNode(Opcodes.ASM5, acc, m.getName(), Type.getMethodDescriptor(m), null, null);
        generateNativeWrapper(mn, mn.name, false);
        if (Configuration.GENERATE_UNINST_STUBS) {
            MethodVisitor mv = super.visitMethod((isInterface ? mn.access : mn.access & ~Opcodes.ACC_ABSTRACT), mn.name + TaintUtils.METHOD_SUFFIX_UNINST, mn.desc, mn.signature, (String[]) mn.exceptions.toArray(new String[0]));
            GeneratorAdapter ga = new GeneratorAdapter(mv, mn.access, mn.name, mn.desc);
            visitAnnotations(mv, mn);
            if (!isInterface) {
                mv.visitCode();
                int opcode;
                if ((mn.access & Opcodes.ACC_STATIC) == 0) {
                    ga.loadThis();
                    opcode = Opcodes.INVOKESPECIAL;
                } else
                    opcode = Opcodes.INVOKESTATIC;
                ga.loadArgs();
                ga.visitMethodInsn(opcode, className, mn.name, mn.desc, false);
                ga.returnValue();
                mv.visitMaxs(0, 0);
                mv.visitEnd();
            }
        }
    }
    if (Configuration.WITH_SELECTIVE_INST) {
        // Make sure that there's a wrapper in place for each method
        for (MethodNode m : methodsToMakeUninstWrappersAround) {
            // these methods were previously renamed to be $$PHOSPHORUNTASGGED
            // first, make one that has a descriptor WITH taint tags, that calls into the uninst one
            generateNativeWrapper(m, m.name + TaintUtils.METHOD_SUFFIX_UNINST, false);
            // next, make one WITHOUT taint tags, and WITHOUT the suffix
            String mName = m.name;
            String mToCall = m.name;
            String descToCall = m.desc;
            boolean isInit = false;
            String mDesc = m.desc;
            if ((Opcodes.ACC_NATIVE & m.access) != 0) {
                mName += TaintUtils.METHOD_SUFFIX_UNINST;
                m.access = m.access & ~Opcodes.ACC_NATIVE;
                mDesc = TaintUtils.remapMethodDescForUninst(mDesc);
            } else if (m.name.equals("<init>")) {
                isInit = true;
                descToCall = mDesc.substring(0, m.desc.indexOf(')')) + Type.getDescriptor(UninstrumentedTaintSentinel.class) + ")" + mDesc.substring(mDesc.indexOf(')') + 1);
                descToCall = TaintUtils.remapMethodDescForUninst(descToCall);
            } else {
                mToCall += TaintUtils.METHOD_SUFFIX_UNINST;
                descToCall = TaintUtils.remapMethodDescForUninst(descToCall);
            }
            MethodVisitor mv = super.visitMethod(m.access, mName, mDesc, m.signature, (String[]) m.exceptions.toArray(new String[0]));
            visitAnnotations(mv, m);
            if (!isInterface) {
                GeneratorAdapter ga = new GeneratorAdapter(mv, m.access, m.name, mDesc);
                mv.visitCode();
                int opcode;
                if ((m.access & Opcodes.ACC_STATIC) == 0) {
                    ga.loadThis();
                    opcode = Opcodes.INVOKESPECIAL;
                } else
                    opcode = Opcodes.INVOKESTATIC;
                Type[] origArgs = Type.getArgumentTypes(m.desc);
                Type[] newArgs = Type.getArgumentTypes(descToCall);
                for (int i = 0; i < origArgs.length; i++) {
                    ga.loadArg(i);
                    if (origArgs[i].getSort() == Type.ARRAY && origArgs[i].getElementType().getSort() != Type.OBJECT && origArgs[i].getDimensions() > 1) {
                        ga.visitMethodInsn(Opcodes.INVOKESTATIC, Type.getInternalName(MultiDTaintedArray.class), "boxIfNecessary", "(Ljava/lang/Object;)Ljava/lang/Object;", false);
                        ga.visitTypeInsn(Opcodes.CHECKCAST, newArgs[i].getInternalName());
                    }
                }
                if (isInit)
                    ga.visitInsn(Opcodes.ACONST_NULL);
                Type retType = Type.getReturnType(m.desc);
                ga.visitMethodInsn(opcode, className, mToCall, descToCall, false);
                if (retType.getSort() == Type.ARRAY && retType.getDimensions() > 1 && retType.getElementType().getSort() != Type.OBJECT) {
                    ga.visitMethodInsn(Opcodes.INVOKESTATIC, Type.getInternalName((Configuration.MULTI_TAINTING ? MultiDTaintedArrayWithObjTag.class : MultiDTaintedArrayWithIntTag.class)), "unboxRaw", "(Ljava/lang/Object;)Ljava/lang/Object;", false);
                    ga.checkCast(retType);
                }
                ga.returnValue();
                mv.visitMaxs(0, 0);
            }
            mv.visitEnd();
        }
    }
    if (Configuration.GENERATE_UNINST_STUBS) {
        // one level deep - and it will call back into instrumented versions
        for (Entry<MethodNode, MethodNode> am : forMore.entrySet()) {
            MethodNode mn = am.getKey();
            if (mn.name.equals("<clinit>"))
                continue;
            String mName = mn.name;
            String mDesc = TaintUtils.remapMethodDescForUninst(mn.desc);
            if (mName.equals("<init>")) {
                mDesc = mDesc.substring(0, mDesc.indexOf(')')) + Type.getDescriptor(UninstrumentedTaintSentinel.class) + ")" + mDesc.substring(mDesc.indexOf(')') + 1);
            } else {
                mName += TaintUtils.METHOD_SUFFIX_UNINST;
            }
            MethodVisitor mv = super.visitMethod(mn.access & ~Opcodes.ACC_NATIVE, mName, mDesc, mn.signature, (String[]) mn.exceptions.toArray(new String[0]));
            MethodNode meth = am.getValue();
            if ((mn.access & Opcodes.ACC_NATIVE) != 0) {
                GeneratorAdapter ga = new GeneratorAdapter(mv, mn.access, mn.name, mn.desc);
                visitAnnotations(mv, mn);
                mv.visitCode();
                int opcode;
                if ((mn.access & Opcodes.ACC_STATIC) == 0) {
                    ga.loadThis();
                    opcode = Opcodes.INVOKESPECIAL;
                } else
                    opcode = Opcodes.INVOKESTATIC;
                Type[] args = Type.getArgumentTypes(mn.desc);
                for (int i = 0; i < args.length; i++) {
                    ga.loadArg(i);
                    if (args[i].getSort() == Type.ARRAY && args[i].getDimensions() > 1 && args[i].getElementType().getSort() != Type.OBJECT) {
                        ga.visitMethodInsn(Opcodes.INVOKESTATIC, Type.getInternalName((Configuration.MULTI_TAINTING ? MultiDTaintedArrayWithObjTag.class : MultiDTaintedArrayWithIntTag.class)), "unboxRaw", "(Ljava/lang/Object;)Ljava/lang/Object;", false);
                        ga.visitTypeInsn(Opcodes.CHECKCAST, args[i].getInternalName());
                    }
                }
                ga.visitMethodInsn(opcode, className, mn.name, mn.desc, false);
                ga.returnValue();
                mv.visitMaxs(0, 0);
                mv.visitEnd();
            } else {
                mv = new SpecialOpcodeRemovingMV(mv, ignoreFrames, className, fixLdcClass);
                NeverNullArgAnalyzerAdapter analyzer = new NeverNullArgAnalyzerAdapter(className, mn.access, mn.name, mDesc, mv);
                mv = analyzer;
                mv = new UninstrumentedReflectionHidingMV(mv, className);
                UninstrumentedReflectionHidingMV ta = (UninstrumentedReflectionHidingMV) mv;
                mv = new UninstrumentedCompatMV(mn.access, className, mn.name, mn.desc, mn.signature, (String[]) mn.exceptions.toArray(new String[0]), mv, analyzer, ignoreFrames);
                LocalVariableManager lvs = new LocalVariableManager(mn.access, mn.desc, mv, analyzer, analyzer, generateExtraLVDebug);
                final PrimitiveArrayAnalyzer primArrayAnalyzer = new PrimitiveArrayAnalyzer(className, mn.access, mn.name, mn.desc, null, null, null);
                lvs.disable();
                lvs.setPrimitiveArrayAnalyzer(primArrayAnalyzer);
                ((UninstrumentedCompatMV) mv).setLocalVariableSorter(lvs);
                ta.setLvs(lvs);
                mv = lvs;
                meth.accept(new MethodVisitor(Opcodes.ASM5) {

                    @Override
                    public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean itf) {
                        // determine if this is going to be uninst, and then if we need to pre-alloc for its return :/
                        if (Configuration.WITH_SELECTIVE_INST && Instrumenter.isIgnoredMethodFromOurAnalysis(owner, name, desc)) {
                        // uninst
                        } else {
                            Type returnType = Type.getReturnType(desc);
                            Type newReturnType = TaintUtils.getContainerReturnType(returnType);
                            if (newReturnType != returnType && !(returnType.getSort() == Type.ARRAY))
                                primArrayAnalyzer.wrapperTypesToPreAlloc.add(newReturnType);
                        }
                    }
                });
                meth.accept(mv);
            }
        }
    }
    // if (!goLightOnGeneratedStuff && TaintUtils.GENERATE_FASTPATH_VERSIONS)
    // for (final MethodNode m : myMethods) {
    // final String oldDesc = m.desc;
    // if (m.name.equals("<init>")) {
    // m.desc = m.desc.substring(0, m.desc.indexOf(")")) + Type.getDescriptor(UninstrumentedTaintSentinel.class) + ")" + Type.getReturnType(m.desc).getDescriptor();
    // } else if (m.name.equals("<clinit>")) {
    // continue;
    // } else {
    // m.name = m.name.replace(TaintUtils.METHOD_SUFFIX, "") + "$$INVIVO_UNINST";
    // }
    // if ((m.access & Opcodes.ACC_ABSTRACT) != 0 && !isInterface) {
    // //Let's see what happens if we make these non-abstract, with no body, to try to fix
    // //problems with jasper usage.
    // m.access = m.access & ~Opcodes.ACC_ABSTRACT;
    // m.instructions = new InsnList();
    // Type ret = Type.getReturnType(m.desc);
    // switch (ret.getSort()) {
    // case Type.BOOLEAN:
    // case Type.BYTE:
    // case Type.CHAR:
    // case Type.SHORT:
    // case Type.INT:
    // m.instructions.add(new InsnNode(Opcodes.ICONST_0));
    // m.instructions.add(new InsnNode(Opcodes.IRETURN));
    // break;
    // case Type.DOUBLE:
    // m.instructions.add(new InsnNode(Opcodes.DCONST_0));
    // m.instructions.add(new InsnNode(Opcodes.DRETURN));
    // break;
    // case Type.FLOAT:
    // m.instructions.add(new InsnNode(Opcodes.FCONST_0));
    // m.instructions.add(new InsnNode(Opcodes.FRETURN));
    // break;
    // case Type.LONG:
    // m.instructions.add(new InsnNode(Opcodes.LCONST_0));
    // m.instructions.add(new InsnNode(Opcodes.LRETURN));
    // break;
    // case Type.ARRAY:
    // case Type.OBJECT:
    // m.instructions.add(new InsnNode(Opcodes.ACONST_NULL));
    // m.instructions.add(new InsnNode(Opcodes.ARETURN));
    // break;
    // case Type.VOID:
    // m.instructions.add(new InsnNode(Opcodes.RETURN));
    // break;
    // }
    // }
    // m.accept(new ClassVisitor(Opcodes.ASM5, this.cv) {
    // @Override
    // public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
    // MethodVisitor mv = super.visitMethod(access, name, desc, signature, exceptions);
    // if (name.equals("<init>")) {
    // mv = new ConstructorArgReindexer(mv, access, name, desc, oldDesc);
    // }
    // return new MethodVisitor(api, mv) {
    // @Override
    // public void visitVarInsn(int opcode, int var) {
    // super.visitVarInsn(opcode, var);
    // }
    // 
    // @Override
    // public void visitMethodInsn(int opcode, String owner, String name, String desc) {
    // if (!Instrumenter.isIgnoredClass(owner)) {
    // if (name.equals("<init>")) {
    // super.visitInsn(Opcodes.ACONST_NULL);
    // desc = desc.substring(0, desc.indexOf(")")) + Type.getDescriptor(UninstrumentedTaintSentinel.class) + ")" + Type.getReturnType(desc).getDescriptor();
    // } else
    // name = name + "$$INVIVO_UNINST";
    // }
    // super.visitMethodInsn(opcode, owner, name, desc);
    // }
    // };
    // }
    // });
    // }
    super.visitEnd();
}
Also used : MultiDTaintedArray(edu.columbia.cs.psl.phosphor.struct.multid.MultiDTaintedArray) FrameNode(org.objectweb.asm.tree.FrameNode) Label(org.objectweb.asm.Label) MultiDTaintedArrayWithIntTag(edu.columbia.cs.psl.phosphor.struct.multid.MultiDTaintedArrayWithIntTag) UninstrumentedTaintSentinel(edu.columbia.cs.psl.phosphor.runtime.UninstrumentedTaintSentinel) MethodVisitor(org.objectweb.asm.MethodVisitor) MethodNode(org.objectweb.asm.tree.MethodNode) MultiDTaintedArrayWithObjTag(edu.columbia.cs.psl.phosphor.struct.multid.MultiDTaintedArrayWithObjTag) FieldNode(org.objectweb.asm.tree.FieldNode) Method(java.lang.reflect.Method) LocalVariableNode(org.objectweb.asm.tree.LocalVariableNode) Type(org.objectweb.asm.Type) NeverNullArgAnalyzerAdapter(edu.columbia.cs.psl.phosphor.instrumenter.analyzer.NeverNullArgAnalyzerAdapter) AnnotationVisitor(org.objectweb.asm.AnnotationVisitor) GeneratorAdapter(org.objectweb.asm.commons.GeneratorAdapter)

Example 4 with NeverNullArgAnalyzerAdapter

use of edu.columbia.cs.psl.phosphor.instrumenter.analyzer.NeverNullArgAnalyzerAdapter in project phosphor by gmu-swe.

the class TaintTrackingClassVisitor method visitMethod.

@Override
public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
    if (name.equals("hashCode") && desc.equals("()I"))
        generateHashCode = false;
    if (name.equals("equals") && desc.equals("(Ljava/lang/Object;)Z"))
        generateEquals = false;
    superMethodsToOverride.remove(name + desc);
    if (name.equals("compareTo"))
        implementsComparable = false;
    if (name.equals("hasAnyTaints"))
        isProxyClass = true;
    // Hack needed for java 7 + integer->tostring fixes
    if ((className.equals("java/lang/Integer") || className.equals("java/lang/Long")) && name.equals("toUnsignedString"))
        access = (access & ~Opcodes.ACC_PRIVATE) | Opcodes.ACC_PUBLIC;
    if (name.contains(TaintUtils.METHOD_SUFFIX)) {
        // Some dynamic stuff might result in there being weird stuff here
        return new MethodVisitor(Opcodes.ASM5) {
        };
    }
    if (Configuration.WITH_SELECTIVE_INST && Instrumenter.isIgnoredMethodFromOurAnalysis(className, name, desc)) {
        // if (TaintUtils.DEBUG_CALLS)
        // System.out.println("Skipping instrumentation for  class: " + className + " method: " + name + " desc: " + desc);
        String newName = name;
        String newDesc = desc;
        if (!name.contains("<") && 0 == (access & Opcodes.ACC_NATIVE))
            newName = name + TaintUtils.METHOD_SUFFIX_UNINST;
        else if (name.equals("<init>")) {
            newDesc = desc.substring(0, desc.indexOf(')')) + Type.getDescriptor(UninstrumentedTaintSentinel.class) + ")" + desc.substring(desc.indexOf(')') + 1);
        }
        newDesc = TaintUtils.remapMethodDescForUninst(newDesc);
        MethodVisitor mv = super.visitMethod(access, newName, newDesc, signature, exceptions);
        mv = new UninstTaintSentinalArgFixer(mv, access, newName, newDesc, desc);
        mv = new SpecialOpcodeRemovingMV(mv, ignoreFrames, className, fixLdcClass);
        MethodVisitor _mv = mv;
        NeverNullArgAnalyzerAdapter analyzer = new NeverNullArgAnalyzerAdapter(className, access, name, newDesc, mv);
        mv = new UninstrumentedReflectionHidingMV(analyzer, className);
        mv = new UninstrumentedCompatMV(access, className, name, newDesc, signature, (String[]) exceptions, mv, analyzer, ignoreFrames);
        LocalVariableManager lvs = new LocalVariableManager(access, newDesc, mv, analyzer, _mv, generateExtraLVDebug);
        ((UninstrumentedCompatMV) mv).setLocalVariableSorter(lvs);
        final PrimitiveArrayAnalyzer primArrayAnalyzer = new PrimitiveArrayAnalyzer(className, access, name, desc, signature, exceptions, null);
        lvs.setPrimitiveArrayAnalyzer(primArrayAnalyzer);
        lvs.disable();
        mv = lvs;
        final MethodVisitor cmv = mv;
        MethodNode wrapper = new MethodNode(Opcodes.ASM5, (isInterface ? access : access & ~Opcodes.ACC_ABSTRACT), name, desc, signature, exceptions) {

            public void visitEnd() {
                super.visitEnd();
                this.accept(cmv);
            }

            public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean itf) {
                // determine if this is going to be uninst, and then if we need to pre-alloc for its return :/
                if (Configuration.WITH_SELECTIVE_INST && Instrumenter.isIgnoredMethod(owner, name, desc)) {
                // uninst
                } else {
                    Type returnType = Type.getReturnType(desc);
                    Type newReturnType = TaintUtils.getContainerReturnType(returnType);
                    if (newReturnType != returnType && !(returnType.getSort() == Type.ARRAY))
                        primArrayAnalyzer.wrapperTypesToPreAlloc.add(newReturnType);
                }
                super.visitMethodInsn(opcode, owner, name, desc, itf);
            }
        };
        if (!name.equals("<clinit>"))
            methodsToMakeUninstWrappersAround.add(wrapper);
        return wrapper;
    }
    if (Configuration.WITH_ENUM_BY_VAL && className.equals("java/lang/Enum") && name.equals("clone"))
        return null;
    if (TaintUtils.DEBUG_CALLS || TaintUtils.DEBUG_FIELDS || TaintUtils.DEBUG_FRAMES || TaintUtils.DEBUG_LOCAL)
        System.out.println("Instrumenting " + name + "\n\n\n\n\n\n");
    if (Instrumenter.IS_KAFFE_INST && className.equals("java/lang/VMSystem"))
        access = access | Opcodes.ACC_PUBLIC;
    else if (Instrumenter.IS_HARMONY_INST && className.endsWith("java/lang/VMMemoryManager")) {
        access = access & ~Opcodes.ACC_PRIVATE;
        access = access | Opcodes.ACC_PUBLIC;
    } else if ((className.equals("java/lang/Integer") || className.equals("java/lang/Long")) && name.equals("getChars")) {
        access = access | Opcodes.ACC_PUBLIC;
    }
    String originalName = name;
    if (FIELDS_ONLY) {
        // || isAnnotation
        return super.visitMethod(access, name, desc, signature, exceptions);
    }
    if (originalName.contains("$$INVIVO")) {
        name = name + "_orig";
    }
    // We will need to add shadow args for each parameter that is a primitive. Because that worked so well last time.
    Type[] argTypes = Type.getArgumentTypes(desc);
    LinkedList<Type> newArgTypes = new LinkedList<Type>();
    boolean isRewrittenDesc = false;
    for (Type t : argTypes) {
        if (t.getSort() == Type.ARRAY) {
            if (t.getElementType().getSort() != Type.OBJECT) {
                if (t.getDimensions() > 1) {
                    newArgTypes.add(MultiDTaintedArray.getTypeForType(t));
                    isRewrittenDesc = true;
                    continue;
                } else {
                    newArgTypes.add(MultiDTaintedArray.getTypeForType(t));
                    isRewrittenDesc = true;
                }
            }
        } else if (t.getSort() != Type.OBJECT) {
            isRewrittenDesc = true;
            newArgTypes.add(Type.getType(Configuration.TAINT_TAG_DESC));
        }
        newArgTypes.add(t);
    }
    if (Configuration.IMPLICIT_TRACKING && !name.equals("<clinit>")) {
        isRewrittenDesc = true;
        newArgTypes.add(Type.getType(ControlTaintTagStack.class));
    }
    if (isRewrittenDesc && name.equals("<init>"))
        newArgTypes.add(Type.getType(TaintSentinel.class));
    // If we are rewriting the return type, also add a param to pass for pre-alloc
    Type oldReturnType = Type.getReturnType(desc);
    Type newReturnType = TaintUtils.getContainerReturnType(Type.getReturnType(desc));
    if ((oldReturnType.getSort() != Type.VOID && oldReturnType.getSort() != Type.OBJECT && oldReturnType.getSort() != Type.ARRAY)) {
        newArgTypes.add(newReturnType);
    }
    Type[] newArgs = new Type[newArgTypes.size()];
    newArgs = newArgTypes.toArray(newArgs);
    boolean requiresNoChange = !isRewrittenDesc && newReturnType.equals(Type.getReturnType(desc));
    MethodNode wrapper = new MethodNode(access, name, desc, signature, exceptions);
    if (!requiresNoChange && !name.equals("<clinit>") && !(name.equals("<init>") && !isRewrittenDesc))
        methodsToAddWrappersFor.add(wrapper);
    String newDesc = Type.getMethodDescriptor(newReturnType, newArgs);
    // System.out.println("olddesc " + desc + " newdesc " + newDesc);
    if ((access & Opcodes.ACC_NATIVE) == 0 && !methodIsTooBigAlready(name, desc)) {
        // not a native method
        if (!name.contains("<") && !requiresNoChange)
            name = name + TaintUtils.METHOD_SUFFIX;
        // if(className.equals("sun/misc/URLClassPath$JarLoader"))
        // System.out.println("\t\t:"+name+newDesc);
        MethodVisitor mv = super.visitMethod(access, name, newDesc, signature, exceptions);
        mv = new TaintTagFieldCastMV(mv);
        MethodVisitor rootmV = mv;
        mv = new SourceSinkTaintingMV(mv, access, className, name, newDesc, desc);
        // mv = new CheckMethodAdapter(mv);
        // mv = new SpecialOpcodeRemovingMV(mv,ignoreFrames, className);
        // mv = reflectionMasker;
        // PropertyDebug debug = new PropertyDebug(Opcodes.ASM4, mv, access, name, newDesc,className);
        MethodVisitor optimizer;
        optimizer = mv;
        // if (DO_OPT)
        // optimizer = new PopOptimizingMV(mv, access, className, name, newDesc, signature, exceptions);
        mv = new SpecialOpcodeRemovingMV(optimizer, ignoreFrames, className, fixLdcClass);
        // optimizer = new PopOptimizingMV(mv, access,className, name, newDesc, signature, exceptions);
        NeverNullArgAnalyzerAdapter analyzer = new NeverNullArgAnalyzerAdapter(className, access, name, newDesc, mv);
        // TODO - how do we handle directbytebuffers?
        mv = new StringTaintVerifyingMV(analyzer, (implementsSerializable || className.startsWith("java/nio/") || className.startsWith("java/io/BUfferedInputStream") || className.startsWith("sun/nio")), analyzer);
        ReflectionHidingMV reflectionMasker = new ReflectionHidingMV(mv, className, name, analyzer);
        PrimitiveBoxingFixer boxFixer = new PrimitiveBoxingFixer(access, className, name, desc, signature, exceptions, reflectionMasker, analyzer);
        LocalVariableManager lvs;
        TaintPassingMV tmv;
        MethodVisitor nextMV;
        {
            // ImplicitTaintRemoverMV implicitCleanup = new ImplicitTaintRemoverMV(access, className, name, desc, signature, exceptions, boxFixer, analyzer);
            tmv = new TaintPassingMV(boxFixer, access, className, name, newDesc, signature, exceptions, desc, analyzer, rootmV);
            tmv.setFields(fields);
            TaintAdapter custom = null;
            lvs = new LocalVariableManager(access, newDesc, tmv, analyzer, mv, generateExtraLVDebug);
            nextMV = lvs;
        }
        MethodArgReindexer mar = new MethodArgReindexer(nextMV, access, name, newDesc, desc, wrapper);
        TaintLoadCoercer tlc = new TaintLoadCoercer(className, access, name, desc, signature, exceptions, mar, ignoreFrames);
        PrimitiveArrayAnalyzer primitiveArrayFixer = new PrimitiveArrayAnalyzer(className, access, name, desc, signature, exceptions, tlc);
        NeverNullArgAnalyzerAdapter preAnalyzer = new NeverNullArgAnalyzerAdapter(className, access, name, desc, primitiveArrayFixer);
        MethodVisitor mvNext = preAnalyzer;
        mvNext = preAnalyzer;
        primitiveArrayFixer.setAnalyzer(preAnalyzer);
        boxFixer.setLocalVariableSorter(lvs);
        tmv.setArrayAnalyzer(primitiveArrayFixer);
        tmv.setLVOffset(mar.getNewArgOffset());
        tmv.setLocalVariableSorter(lvs);
        // i'm lazy. this guy will tell the LVS what return types to prealloc
        lvs.setPrimitiveArrayAnalyzer(primitiveArrayFixer);
        reflectionMasker.setLvs(lvs);
        // if(IS_RUNTIME_INST)
        // {
        // return mvNext;
        // }
        final MethodVisitor prev = mvNext;
        MethodNode rawMethod = new MethodNode(Opcodes.ASM5, access, name, desc, signature, exceptions) {

            @Override
            protected LabelNode getLabelNode(Label l) {
                if (!Configuration.READ_AND_SAVE_BCI)
                    return super.getLabelNode(l);
                if (!(l.info instanceof LabelNode)) {
                    l.info = new LabelNode(l);
                }
                return (LabelNode) l.info;
            }

            @Override
            public void visitEnd() {
                super.visitEnd();
                this.accept(prev);
            }
        };
        if (!isInterface && !originalName.contains("$$INVIVO"))
            this.myMethods.add(rawMethod);
        forMore.put(wrapper, rawMethod);
        if (Configuration.extensionMethodVisitor != null) {
            try {
                TaintAdapter custom = Configuration.extensionMethodVisitor.getConstructor(Integer.TYPE, String.class, String.class, String.class, String.class, String[].class, MethodVisitor.class, NeverNullArgAnalyzerAdapter.class, String.class, String.class).newInstance(access, className, name, desc, signature, exceptions, rawMethod, null, classSource, classDebug);
                custom.setFields(fields);
                custom.setSuperName(superName);
                return custom;
            } catch (InstantiationException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (IllegalArgumentException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            } catch (NoSuchMethodException e) {
                e.printStackTrace();
            } catch (SecurityException e) {
                e.printStackTrace();
            }
        }
        return rawMethod;
    } else {
        // this is a native method. we want here to make a $taint method that will call the original one.
        final MethodVisitor prev = super.visitMethod(access, name, desc, signature, exceptions);
        MethodNode rawMethod = new MethodNode(Opcodes.ASM5, access, name, desc, signature, exceptions) {

            @Override
            public void visitEnd() {
                super.visitEnd();
                this.accept(prev);
            }
        };
        forMore.put(wrapper, rawMethod);
        return rawMethod;
    }
}
Also used : LabelNode(org.objectweb.asm.tree.LabelNode) Label(org.objectweb.asm.Label) UninstrumentedTaintSentinel(edu.columbia.cs.psl.phosphor.runtime.UninstrumentedTaintSentinel) MethodVisitor(org.objectweb.asm.MethodVisitor) MethodNode(org.objectweb.asm.tree.MethodNode) LinkedList(java.util.LinkedList) InvocationTargetException(java.lang.reflect.InvocationTargetException) ControlTaintTagStack(edu.columbia.cs.psl.phosphor.struct.ControlTaintTagStack) Type(org.objectweb.asm.Type) NeverNullArgAnalyzerAdapter(edu.columbia.cs.psl.phosphor.instrumenter.analyzer.NeverNullArgAnalyzerAdapter)

Example 5 with NeverNullArgAnalyzerAdapter

use of edu.columbia.cs.psl.phosphor.instrumenter.analyzer.NeverNullArgAnalyzerAdapter in project phosphor by gmu-swe.

the class DebugPrinter method main.

public static void main(String[] args) throws Exception {
    // Configuration.IMPLICIT_TRACKING = true;
    File clazz = new File(args[0]);
    final ClassReader cr1 = new ClassReader(new FileInputStream(clazz));
    PrintWriter pw = new PrintWriter(new FileWriter("z.txt"));
    ClassWriter cw1 = new ClassWriter(ClassWriter.COMPUTE_FRAMES) {

        @Override
        protected String getCommonSuperClass(String type1, String type2) {
            try {
                return super.getCommonSuperClass(type1, type2);
            } catch (Exception ex) {
                // System.err.println("err btwn " + type1 + " " +type2);
                return "java/lang/Unknown";
            }
        }
    };
    cr1.accept(new ClassVisitor(Opcodes.ASM4, cw1) {

        @Override
        public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
            // TODO Auto-generated method stub
            return new JSRInlinerAdapter(super.visitMethod(access, name, desc, signature, exceptions), access, name, desc, signature, exceptions);
        }
    }, ClassReader.EXPAND_FRAMES);
    final ClassReader cr = new ClassReader(cw1.toByteArray());
    TraceClassVisitor tcv = new TraceClassVisitor(new ClassVisitor(Opcodes.ASM5, new ClassWriter(0)) {

        String className;

        @Override
        public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {
            super.visit(version, access, name, signature, superName, interfaces);
            this.className = name;
        }

        @Override
        public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
            // TODO Auto-generated method stub
            MethodVisitor mv = super.visitMethod(access, name, desc, signature, exceptions);
            mv = new PrimitiveArrayAnalyzer(cr.getClassName(), access, name, desc, signature, exceptions, mv);
            NeverNullArgAnalyzerAdapter an = new NeverNullArgAnalyzerAdapter(cr.getClassName(), access, name, desc, mv);
            ((PrimitiveArrayAnalyzer) mv).setAnalyzer(an);
            mv = an;
            return mv;
        }
    }, pw);
    cr.accept(tcv, ClassReader.EXPAND_FRAMES);
    pw.flush();
}
Also used : FileWriter(java.io.FileWriter) TraceClassVisitor(org.objectweb.asm.util.TraceClassVisitor) ClassVisitor(org.objectweb.asm.ClassVisitor) FileInputStream(java.io.FileInputStream) ClassWriter(org.objectweb.asm.ClassWriter) JSRInlinerAdapter(org.objectweb.asm.commons.JSRInlinerAdapter) MethodVisitor(org.objectweb.asm.MethodVisitor) PrimitiveArrayAnalyzer(edu.columbia.cs.psl.phosphor.instrumenter.PrimitiveArrayAnalyzer) TraceClassVisitor(org.objectweb.asm.util.TraceClassVisitor) NeverNullArgAnalyzerAdapter(edu.columbia.cs.psl.phosphor.instrumenter.analyzer.NeverNullArgAnalyzerAdapter) ClassReader(org.objectweb.asm.ClassReader) File(java.io.File) PrintWriter(java.io.PrintWriter)

Aggregations

NeverNullArgAnalyzerAdapter (edu.columbia.cs.psl.phosphor.instrumenter.analyzer.NeverNullArgAnalyzerAdapter)5 MethodVisitor (org.objectweb.asm.MethodVisitor)5 Label (org.objectweb.asm.Label)3 Type (org.objectweb.asm.Type)3 UninstrumentedTaintSentinel (edu.columbia.cs.psl.phosphor.runtime.UninstrumentedTaintSentinel)2 MultiDTaintedArray (edu.columbia.cs.psl.phosphor.struct.multid.MultiDTaintedArray)2 MultiDTaintedArrayWithIntTag (edu.columbia.cs.psl.phosphor.struct.multid.MultiDTaintedArrayWithIntTag)2 MultiDTaintedArrayWithObjTag (edu.columbia.cs.psl.phosphor.struct.multid.MultiDTaintedArrayWithObjTag)2 FileInputStream (java.io.FileInputStream)2 PrintWriter (java.io.PrintWriter)2 LinkedList (java.util.LinkedList)2 ClassReader (org.objectweb.asm.ClassReader)2 ClassVisitor (org.objectweb.asm.ClassVisitor)2 ClassWriter (org.objectweb.asm.ClassWriter)2 GeneratorAdapter (org.objectweb.asm.commons.GeneratorAdapter)2 JSRInlinerAdapter (org.objectweb.asm.commons.JSRInlinerAdapter)2 FieldNode (org.objectweb.asm.tree.FieldNode)2 FrameNode (org.objectweb.asm.tree.FrameNode)2 LabelNode (org.objectweb.asm.tree.LabelNode)2 LocalVariableNode (org.objectweb.asm.tree.LocalVariableNode)2