Search in sources :

Example 21 with LocalVariableNode

use of org.objectweb.asm.tree.LocalVariableNode in project felix by apache.

the class MethodDescriptor method addLocalVariable.

public void addLocalVariable(String name, String desc, String signature, int index) {
    m_locals.put(index, new LocalVariableNode(name, desc, signature, null, null, index));
    if (index >= m_argsVarLength) {
        // keep only argument-related local variables definitions (others relate to code which isn't in this method)
        return;
    }
    if (m_argLocalVariables == null) {
        m_argLocalVariables = new ArrayList<LocalVariableNode>();
    }
    m_argLocalVariables.add(new LocalVariableNode(name, desc, signature, null, null, index));
}
Also used : LocalVariableNode(org.objectweb.asm.tree.LocalVariableNode)

Example 22 with LocalVariableNode

use of org.objectweb.asm.tree.LocalVariableNode in project phosphor by gmu-swe.

the class TaintAdapter method storeToLocals.

/**
 * Stores the top n stack elements as local variables. Returns an array of
 * all of the lv indices. return[0] is the top element.
 *
 * @param n
 * @return
 */
protected LocalVariableNode[] storeToLocals(int n) {
    LocalVariableNode[] ret = new LocalVariableNode[n];
    // System.out.println(analyzer.stack);
    for (int i = 0; i < n; i++) {
        Type elType = null;
        if (analyzer.stack.get(analyzer.stack.size() - 1) == Opcodes.TOP)
            elType = getTypeForStackType(analyzer.stack.get(analyzer.stack.size() - 2));
        else
            elType = getTypeForStackType(analyzer.stack.get(analyzer.stack.size() - 1));
        Boolean istagged = topCarriesTaint();
        ret[i] = new LocalVariableNode(null, elType.getDescriptor(), istagged.toString(), null, null, lvs.getTmpLV());
        super.visitVarInsn(elType.getOpcode(ISTORE), ret[i].index);
    }
    return ret;
}
Also used : Type(org.objectweb.asm.Type) LocalVariableNode(org.objectweb.asm.tree.LocalVariableNode)

Example 23 with LocalVariableNode

use of org.objectweb.asm.tree.LocalVariableNode in project phosphor by gmu-swe.

the class TaintPassingMV method visitInsn.

@Override
public void visitInsn(int opcode) {
    // System.out.println(name+" "+PhosphorTextifier.MORE_OPCODES[opcode-200]);
    if (opcode == TaintUtils.CUSTOM_SIGNAL_1 || opcode == TaintUtils.CUSTOM_SIGNAL_2 || opcode == TaintUtils.CUSTOM_SIGNAL_3 || opcode == TaintUtils.LOOP_HEADER) {
        Configuration.taintTagFactory.signalOp(opcode, null);
        super.visitInsn(opcode);
        return;
    }
    if (opcode == TaintUtils.DUP_TAINT_AT_0) {
        nextDupCopiesTaint0 = true;
        return;
    }
    if (opcode == TaintUtils.DUP_TAINT_AT_1) {
        nextDupCopiesTaint1 = true;
        return;
    }
    if (opcode == TaintUtils.DUP_TAINT_AT_2) {
        nextDupCopiesTaint2 = true;
        return;
    }
    if (opcode == TaintUtils.DUP_TAINT_AT_3) {
        nextDupCopiesTaint3 = true;
        return;
    }
    if (opcode == TaintUtils.TRACKED_LOAD) {
        nextLoadisTracked = true;
        super.visitInsn(opcode);
        return;
    }
    if (opcode == TaintUtils.FORCE_CTRL_STORE) {
        // If there is anything on the stack right now, apply the current marker to it
        if (analyzer.stack.isEmpty() || topOfStackIsNull())
            return;
        Type onStack = getTopOfStackType();
        if (onStack.getSort() != Type.OBJECT && onStack.getSort() != Type.ARRAY) {
            if (onStack.getSize() == 1) {
                super.visitInsn(SWAP);
                super.visitVarInsn(ALOAD, lvs.getIdxOfMasterControlLV());
                super.visitMethodInsn(INVOKESTATIC, Configuration.MULTI_TAINT_HANDLER_CLASS, "combineTags", "(" + Configuration.TAINT_TAG_DESC + "Ledu/columbia/cs/psl/phosphor/struct/ControlTaintTagStack;)" + Configuration.TAINT_TAG_DESC, false);
                super.visitInsn(SWAP);
            } else {
                super.visitInsn(DUP2_X1);
                super.visitInsn(POP2);
                super.visitVarInsn(ALOAD, lvs.getIdxOfMasterControlLV());
                super.visitMethodInsn(INVOKESTATIC, Configuration.MULTI_TAINT_HANDLER_CLASS, "combineTags", "(" + Configuration.TAINT_TAG_DESC + "Ledu/columbia/cs/psl/phosphor/struct/ControlTaintTagStack;)" + Configuration.TAINT_TAG_DESC, false);
                super.visitInsn(DUP_X2);
                super.visitInsn(POP);
            }
        } else {
            super.visitInsn(DUP);
            super.visitVarInsn(ALOAD, lvs.getIdxOfMasterControlLV());
            super.visitMethodInsn(INVOKESTATIC, Configuration.MULTI_TAINT_HANDLER_CLASS, "combineTagsOnObject", "(Ljava/lang/Object;Ledu/columbia/cs/psl/phosphor/struct/ControlTaintTagStack;)V", false);
        }
        return;
    }
    if (opcode == TaintUtils.RAW_INSN) {
        isRawInsns = !isRawInsns;
        return;
    }
    if (opcode == TaintUtils.IGNORE_EVERYTHING) {
        // System.err.println("VisitInsn is ignoreverything! in  " + name);
        // new Exception().printStackTrace();
        isIgnoreAllInstrumenting = !isIgnoreAllInstrumenting;
        isIgnoreEverything = !isIgnoreEverything;
        Configuration.taintTagFactory.signalOp(opcode, null);
        super.visitInsn(opcode);
        return;
    }
    if (opcode == TaintUtils.NO_TAINT_STORE_INSN) {
        isTaintlessArrayStore = true;
        return;
    }
    if (isIgnoreAllInstrumenting || isRawInsns) {
        super.visitInsn(opcode);
        return;
    }
    if (Configuration.IMPLICIT_TRACKING && !Configuration.WITHOUT_PROPOGATION) {
        switch(opcode) {
            // case LRETURN:
            case ATHROW:
                for (int i = 1; i < taintTagsLoggedAtJumps.length; i++) {
                    passthruMV.visitVarInsn(ALOAD, lvs.getIdxOfMasterControlLV());
                    passthruMV.visitVarInsn(ALOAD, taintTagsLoggedAtJumps[i]);
                    passthruMV.visitMethodInsn(INVOKEVIRTUAL, Type.getInternalName(ControlTaintTagStack.class), "pop", "(" + "Ledu/columbia/cs/psl/phosphor/struct/EnqueuedTaint;" + ")V", false);
                }
                break;
        }
    }
    switch(opcode) {
        case Opcodes.NOP:
            super.visitInsn(opcode);
            break;
        case Opcodes.ACONST_NULL:
            // System.out.println("NULL at" + curLabel);
            // System.out.println("NULL IN " + curLabel);
            super.visitInsn(opcode);
            if (nextLoadisTracked) {
                nextLoadisTracked = false;
                super.visitInsn(ACONST_NULL);
                analyzer.setTopOfStackTagged();
            }
            break;
        case Opcodes.ICONST_M1:
        case Opcodes.ICONST_0:
        case Opcodes.ICONST_1:
        case Opcodes.ICONST_2:
        case Opcodes.ICONST_3:
        case Opcodes.ICONST_4:
        case Opcodes.ICONST_5:
        case Opcodes.LCONST_0:
        case Opcodes.LCONST_1:
        case Opcodes.FCONST_0:
        case Opcodes.FCONST_1:
        case Opcodes.FCONST_2:
        case Opcodes.DCONST_0:
        case Opcodes.DCONST_1:
            if (nextLoadisTracked) {
                if (Configuration.IMPLICIT_TRACKING || Configuration.IMPLICIT_LIGHT_TRACKING) {
                    super.visitVarInsn(ALOAD, lvs.idxOfMasterControlLV);
                    super.visitMethodInsn(INVOKEVIRTUAL, "edu/columbia/cs/psl/phosphor/struct/ControlTaintTagStack", "copyTag", "()" + Configuration.TAINT_TAG_DESC, false);
                } else
                    super.visitInsn(Configuration.NULL_TAINT_LOAD_OPCODE);
                nextLoadisTracked = false;
                super.visitInsn(opcode);
                analyzer.setTopOfStackTagged();
            } else
                super.visitInsn(opcode);
            return;
        case Opcodes.LALOAD:
        case Opcodes.DALOAD:
        case Opcodes.IALOAD:
        case Opcodes.FALOAD:
        case Opcodes.BALOAD:
        case Opcodes.CALOAD:
        case Opcodes.SALOAD:
            Type taintType = Type.getType(Configuration.TAINT_TAG_DESC);
            boolean doingLoadWithIdxTaint = false;
            if (Configuration.ARRAY_INDEX_TRACKING && topCarriesTaint()) {
                if (nextLoadisTracked)
                    doingLoadWithIdxTaint = true;
                else {
                    super.visitInsn(SWAP);
                    super.visitInsn(POP);
                    analyzer.clearTopOfStackTagged();
                }
            }
            String elType = null;
            String elName = null;
            switch(opcode) {
                case Opcodes.LALOAD:
                    elName = "Long";
                    elType = "J";
                    break;
                case Opcodes.DALOAD:
                    elName = "Double";
                    elType = "D";
                    break;
                case Opcodes.IALOAD:
                    elName = "Int";
                    elType = "I";
                    break;
                case Opcodes.FALOAD:
                    elName = "Float";
                    elType = "F";
                    break;
                case Opcodes.BALOAD:
                    elName = "Byte";
                    // System.out.println("BALOAD " + analyzer.stack);
                    if (analyzer.stack.get(analyzer.stack.size() - (doingLoadWithIdxTaint ? 3 : 2)) instanceof Integer)
                        elType = "B";
                    else {
                        elType = Type.getType((String) analyzer.stack.get(analyzer.stack.size() - (doingLoadWithIdxTaint ? 3 : 2))).getElementType().getDescriptor();
                    }
                    break;
                case Opcodes.CALOAD:
                    elName = "Char";
                    elType = "C";
                    break;
                case Opcodes.SALOAD:
                    elName = "Short";
                    elType = "S";
                    break;
            }
            if (TaintUtils.DEBUG_FRAMES)
                System.out.println(name + desc + "PRE XALOAD " + elType + ": " + analyzer.stack + "; " + analyzer.locals);
            if (analyzer.stackTagStatus.get(analyzer.stackTagStatus.size() - (doingLoadWithIdxTaint ? 3 : 2)) instanceof TaggedValue || nextLoadisTracked) {
                // TA A T I
                if (elType.equals("Z"))
                    elName = "Boolean";
                Type retType = Type.getObjectType("edu/columbia/cs/psl/phosphor/struct/Tainted" + elName + "With" + (Configuration.MULTI_TAINTING ? "Obj" : "Int") + "Tag");
                int prealloc = lvs.getPreAllocedReturnTypeVar(retType);
                super.visitVarInsn(ALOAD, prealloc);
                String methodName = "get";
                if (Configuration.IMPLICIT_TRACKING || Configuration.IMPLICIT_LIGHT_TRACKING) {
                    super.visitVarInsn(ALOAD, lvs.idxOfMasterControlLV);
                }
                super.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "edu/columbia/cs/psl/phosphor/struct/Lazy" + elName + "Array" + (Configuration.MULTI_TAINTING ? "Obj" : "Int") + "Tags", methodName, "(" + "[" + elType + (doingLoadWithIdxTaint ? Configuration.TAINT_TAG_DESC : "") + "I" + retType.getDescriptor() + (Configuration.IMPLICIT_TRACKING || Configuration.IMPLICIT_LIGHT_TRACKING ? "Ledu/columbia/cs/psl/phosphor/struct/ControlTaintTagStack;" : "") + ")" + retType.getDescriptor(), false);
                if (nextLoadisTracked) {
                    super.visitInsn(DUP);
                    super.visitFieldInsn(GETFIELD, retType.getInternalName(), "taint", Configuration.TAINT_TAG_DESC);
                    super.visitInsn(SWAP);
                    super.visitFieldInsn(GETFIELD, retType.getInternalName(), "val", elType);
                    nextLoadisTracked = false;
                    analyzer.setTopOfStackTagged();
                } else {
                    super.visitFieldInsn(GETFIELD, retType.getInternalName(), "val", elType);
                }
            } else {
                super.visitInsn(opcode);
            }
            break;
        case Opcodes.AALOAD:
            int lvForIdxtaint = -1;
            taintType = Type.getType(Configuration.TAINT_TAG_DESC);
            if (Configuration.ARRAY_INDEX_TRACKING && topCarriesTaint()) {
                super.visitInsn(SWAP);
                lvForIdxtaint = lvs.getTmpLV(taintType);
                super.visitVarInsn(taintType.getOpcode(ISTORE), lvForIdxtaint);
                analyzer.clearTopOfStackTagged();
            }
            // ?TA A I
            // System.out.println("AALOAD " + analyzer.stackTagStatus);
            Object arrayType = analyzer.stack.get(analyzer.stack.size() - 2);
            Type t = getTypeForStackType(arrayType);
            if (t.getDimensions() == 1 && t.getElementType().getDescriptor().startsWith("Ledu/columbia/cs/psl/phosphor/struct/Lazy")) {
                super.visitInsn(opcode);
                try {
                    retrieveTaintedArray("[" + (MultiDTaintedArray.getPrimitiveTypeForWrapper(Class.forName(t.getElementType().getInternalName().replace("/", ".")))));
                    if (!nextLoadisTracked) {
                        super.visitInsn(SWAP);
                        super.visitInsn(POP);
                    } else
                        analyzer.setTopOfStackTagged();
                    nextLoadisTracked = false;
                } catch (Exception e) {
                    e.printStackTrace();
                }
            } else
                super.visitInsn(opcode);
            if (lvForIdxtaint >= 0) {
                super.visitInsn(DUP);
                super.visitVarInsn(taintType.getOpcode(ILOAD), lvForIdxtaint);
                super.visitMethodInsn(INVOKESTATIC, Configuration.MULTI_TAINT_HANDLER_CLASS, "combineTagsInPlace", "(Ljava/lang/Object;" + Configuration.TAINT_TAG_DESC + ")V", false);
                lvs.freeTmpLV(lvForIdxtaint);
            }
            break;
        case Opcodes.AASTORE:
            arrayType = analyzer.stack.get(analyzer.stack.size() - 1);
            t = getTypeForStackType(arrayType);
            // Type taintArrayType = getTypeForStackType(analyzer.stack.get(analyzer.stack.size() - 2));
            // System.out.println("AASTORE of " + arrayType + " ONTO ...");
            // System.out.println(analyzer.stack);
            // better look to see if we are storing a NULL into a multidemnsional array...
            boolean idxTainted = Configuration.ARRAY_INDEX_TRACKING && analyzer.stackTagStatus.get(analyzer.stack.size() - (topCarriesTaint() ? 1 : 0) - 2) instanceof TaggedValue;
            if (arrayType == Opcodes.NULL) {
                Object theArray = analyzer.stack.get(analyzer.stack.size() - 3 - (idxTainted ? 1 : 0));
                t = getTypeForStackType(theArray);
                // System.out.println(theArray);
                if (theArray != Opcodes.NULL && t.getElementType().getSort() != Type.OBJECT)
                    super.visitInsn(ACONST_NULL);
            }
            if (t.getSort() == Type.ARRAY && t.getElementType().getDescriptor().length() == 1) {
                // this is a multi-d array. make it work, even if it's nasty.
                if (!analyzer.isTopOfStackTagged()) {
                    super.visitTypeInsn(NEW, MultiDTaintedArray.getTypeForType(t).getInternalName());
                    super.visitInsn(DUP_X1);
                    super.visitInsn(SWAP);
                    super.visitMethodInsn(INVOKESPECIAL, MultiDTaintedArray.getTypeForType(t).getInternalName(), "<init>", "(" + t + ")V", false);
                    nextLoadisTracked = false;
                // analyzer.setTopOfStackTagged();
                } else
                    registerTaintedArray();
                if (Configuration.IMPLICIT_TRACKING || Configuration.IMPLICIT_LIGHT_TRACKING) {
                    super.visitInsn(DUP);
                    super.visitVarInsn(ALOAD, lvs.getIdxOfMasterControlLV());
                    super.visitMethodInsn(INVOKESTATIC, Configuration.MULTI_TAINT_HANDLER_CLASS, "combineTagsOnObject", "(Ljava/lang/Object;Ledu/columbia/cs/psl/phosphor/struct/ControlTaintTagStack;)V", false);
                }
                if (idxTainted) {
                    // Array Taint Index Val
                    super.visitInsn(DUP2_X1);
                    // Array I V T I V
                    super.visitInsn(SWAP);
                    super.visitInsn(POP);
                    // Array I V T V
                    super.visitInsn(SWAP);
                    // Array  I V V T
                    super.visitMethodInsn(INVOKESTATIC, Configuration.MULTI_TAINT_HANDLER_CLASS, "combineTagsInPlace", "(Ljava/lang/Object;" + Configuration.TAINT_TAG_DESC + ")V", false);
                }
                super.visitInsn(opcode);
            } else {
                if (Configuration.IMPLICIT_TRACKING || Configuration.IMPLICIT_LIGHT_TRACKING) {
                    super.visitInsn(DUP);
                    super.visitVarInsn(ALOAD, lvs.getIdxOfMasterControlLV());
                    super.visitMethodInsn(INVOKESTATIC, Configuration.MULTI_TAINT_HANDLER_CLASS, "combineTagsOnObject", "(Ljava/lang/Object;Ledu/columbia/cs/psl/phosphor/struct/ControlTaintTagStack;)V", false);
                }
                if (idxTainted) {
                    // Array T I V
                    super.visitInsn(DUP2_X1);
                    // Array I V T I V
                    super.visitInsn(SWAP);
                    super.visitInsn(POP);
                    // Array I V T V
                    super.visitInsn(SWAP);
                    // Array  I V V T
                    super.visitMethodInsn(INVOKESTATIC, Configuration.MULTI_TAINT_HANDLER_CLASS, "combineTagsInPlace", "(Ljava/lang/Object;" + Configuration.TAINT_TAG_DESC + ")V", false);
                }
                super.visitInsn(opcode);
            }
            break;
        case Opcodes.IASTORE:
        case Opcodes.LASTORE:
        case Opcodes.FASTORE:
        case Opcodes.DASTORE:
        case Opcodes.BASTORE:
        case Opcodes.CASTORE:
        case Opcodes.SASTORE:
            // public static void XASTORE(int[] TArray, int[] Array, int idxTaint, int idx, int valTaint, int val) {
            int valStoreOpcode;
            int valLoadOpcode;
            Object beingStored = analyzer.stackTagStatus.get(analyzer.stackTagStatus.size() - (opcode == LASTORE || opcode == DASTORE ? 2 : 1));
            int offsetToArray = 4;
            int ob = (opcode == LASTORE || opcode == DASTORE ? 2 : 1) + ((beingStored instanceof TaggedValue) ? 1 : 0) + 1;
            boolean tagIsTracked = Configuration.ARRAY_INDEX_TRACKING && analyzer.stackTagStatus.get(analyzer.stackTagStatus.size() - ob) instanceof TaggedValue;
            if (tagIsTracked)
                offsetToArray++;
            switch(opcode) {
                case Opcodes.LASTORE:
                    valStoreOpcode = LSTORE;
                    valLoadOpcode = LLOAD;
                    elType = "J";
                    offsetToArray++;
                    break;
                case Opcodes.DASTORE:
                    valStoreOpcode = DSTORE;
                    valLoadOpcode = DLOAD;
                    elType = "D";
                    offsetToArray++;
                    break;
                case Opcodes.IASTORE:
                    valStoreOpcode = ISTORE;
                    valLoadOpcode = ILOAD;
                    elType = "I";
                    break;
                case Opcodes.FASTORE:
                    valStoreOpcode = FSTORE;
                    valLoadOpcode = FLOAD;
                    elType = "F";
                    break;
                case Opcodes.BASTORE:
                    elType = "B";
                    if (beingStored instanceof TaggedValue) {
                        elType = Type.getType((String) analyzer.stack.get(analyzer.stack.size() - offsetToArray)).getElementType().getDescriptor();
                        if (elType.equals("Z"))
                            elName = "Boolean";
                    }
                    valStoreOpcode = ISTORE;
                    valLoadOpcode = ILOAD;
                    break;
                case Opcodes.CASTORE:
                    valLoadOpcode = ILOAD;
                    valStoreOpcode = ISTORE;
                    elType = "C";
                    break;
                case Opcodes.SASTORE:
                    valLoadOpcode = ILOAD;
                    valStoreOpcode = ISTORE;
                    elType = "S";
                    break;
                default:
                    valLoadOpcode = -1;
                    valStoreOpcode = -1;
                    elType = null;
            }
            if (TaintUtils.DEBUG_FRAMES) {
                System.out.println("XASTORE>>>" + elType);
                System.out.println(beingStored);
                System.out.println(analyzer.stackTagStatus);
                System.out.println(analyzer.stack);
            }
            if (!(beingStored instanceof TaggedValue)) {
                // System.out.println(offsetToArray);
                if (tagIsTracked) {
                    String typ = (String) analyzer.stack.get(analyzer.stack.size() - offsetToArray);
                    super.visitMethodInsn(Opcodes.INVOKEVIRTUAL, typ, "set", "([" + elType + Configuration.TAINT_TAG_DESC + "I" + elType + ")V", false);
                } else
                    super.visitInsn(opcode);
            } else if (analyzer.stackTagStatus.get(analyzer.stack.size() - offsetToArray) instanceof TaggedValue) {
                String typ = (String) analyzer.stack.get(analyzer.stack.size() - offsetToArray - 1);
                if (Configuration.IMPLICIT_TRACKING || Configuration.IMPLICIT_LIGHT_TRACKING) {
                    super.visitVarInsn(ALOAD, lvs.idxOfMasterControlLV);
                    if (tagIsTracked)
                        super.visitMethodInsn(Opcodes.INVOKEVIRTUAL, typ, "set", "([" + elType + Configuration.TAINT_TAG_DESC + "I" + Configuration.TAINT_TAG_DESC + elType + "Ledu/columbia/cs/psl/phosphor/struct/ControlTaintTagStack;)V", false);
                    else
                        super.visitMethodInsn(Opcodes.INVOKEVIRTUAL, typ, "set", "([" + elType + "I" + Configuration.TAINT_TAG_DESC + elType + "Ledu/columbia/cs/psl/phosphor/struct/ControlTaintTagStack;)V", false);
                } else if (tagIsTracked)
                    super.visitMethodInsn(Opcodes.INVOKEVIRTUAL, typ, "set", "([" + elType + Configuration.TAINT_TAG_DESC + "I" + Configuration.TAINT_TAG_DESC + elType + ")V", false);
                else
                    super.visitMethodInsn(Opcodes.INVOKEVIRTUAL, typ, "set", "([" + elType + "I" + Configuration.TAINT_TAG_DESC + elType + ")V", false);
            } else {
                if (tagIsTracked)
                    throw new IllegalStateException(analyzer.stackTagStatus.toString());
                super.visitInsn(opcode);
            }
            isTaintlessArrayStore = false;
            break;
        case Opcodes.POP:
            if (topCarriesTaint()) {
                super.visitInsn(POP2);
                return;
            }
            super.visitInsn(opcode);
            return;
        case Opcodes.POP2:
            if (topCarriesTaint()) {
                super.visitInsn(POP2);
                if (topCarriesTaint())
                    super.visitInsn(POP2);
                else
                    super.visitInsn(POP);
                return;
            } else if (analyzer.stackTagStatus.get(analyzer.stackTagStatus.size() - 2) instanceof TaggedValue) {
                super.visitInsn(POP);
                super.visitInsn(POP2);
            } else
                super.visitInsn(opcode);
            return;
        case Opcodes.DUP:
            if (nextDupCopiesTaint0 && nextDupCopiesTaint1) {
                super.visitInsn(Opcodes.DUP2);
            } else if (!nextDupCopiesTaint0 && nextDupCopiesTaint1) {
                super.visitInsn(DUP_X1);
                analyzer.stackTagStatus.set(analyzer.stack.size() - 3, analyzer.stack.get(analyzer.stack.size() - 3));
            } else if (nextDupCopiesTaint0 && !nextDupCopiesTaint1) {
                super.visitInsn(DUP);
                analyzer.stackTagStatus.set(analyzer.stack.size() - 1, analyzer.stack.get(analyzer.stack.size() - 1));
            } else {
                // TOP should never be tainted and reach here
                super.visitInsn(Opcodes.DUP);
            }
            nextDupCopiesTaint0 = false;
            nextDupCopiesTaint1 = false;
            nextDupCopiesTaint2 = false;
            nextDupCopiesTaint3 = false;
            break;
        case Opcodes.DUP2:
            Object topOfStack = analyzer.stackTagStatus.get(analyzer.stackTagStatus.size() - 1);
            // 0 1 -> 0 1 2 3
            if (getStackElementSize(topOfStack) == 1) {
                if (nextDupCopiesTaint0) {
                    int offset = 2;
                    if (topCarriesTaint())
                        offset++;
                    // 3, or 2?
                    Object secondOnStack = analyzer.stackTagStatus.get(analyzer.stackTagStatus.size() - offset);
                    if (!(secondOnStack instanceof TaggedValue)) {
                        if (nextDupCopiesTaint1 && !nextDupCopiesTaint2 && !nextDupCopiesTaint3) {
                            // Dup the top 2 items, leaving a taint behind for the top item, the second item is not tainted
                            // A TB B -> A TB B A TB B
                            LocalVariableNode[] lvs = storeToLocals(3);
                            loadLV(2, lvs);
                            loadLV(1, lvs);
                            loadLV(0, lvs);
                            loadLV(2, lvs);
                            loadLV(1, lvs);
                            loadLV(0, lvs);
                            freeLVs(lvs);
                            return;
                        }
                        throw new IllegalStateException("Told to copy taint of second thing on stack but got " + secondOnStack);
                    }
                    if (getStackElementSize(secondOnStack) == 2)
                        // Should be true always or was invalid already
                        throw new UnsupportedOperationException();
                    if (nextDupCopiesTaint1) {
                        if (nextDupCopiesTaint2) {
                            if (nextDupCopiesTaint3) {
                                // 0, 1, 2, 3
                                LocalVariableNode[] lvs = storeToLocals(4);
                                loadLV(3, lvs);
                                loadLV(2, lvs);
                                loadLV(1, lvs);
                                loadLV(0, lvs);
                                loadLV(3, lvs);
                                loadLV(2, lvs);
                                loadLV(1, lvs);
                                loadLV(0, lvs);
                                freeLVs(lvs);
                            } else {
                                // 0, 1, 2, !3
                                LocalVariableNode[] lvs = storeToLocals(4);
                                loadLV(3, lvs);
                                loadLV(2, lvs);
                                loadLV(1, lvs);
                                loadLV(0, lvs);
                                loadLV(3, lvs);
                                loadLV(2, lvs);
                                // loadLV(1, lvs);
                                loadLV(0, lvs);
                                analyzer.clearTopOfStackTagged();
                                freeLVs(lvs);
                            }
                        } else {
                            if (nextDupCopiesTaint3) {
                                // 0, 1, !2, 3
                                throw new UnsupportedOperationException();
                            } else {
                                // 0,1,!2,!3
                                throw new UnsupportedOperationException();
                            }
                        }
                    } else {
                        if (nextDupCopiesTaint2) {
                            if (nextDupCopiesTaint3) {
                                // 0, !1, 2, 3
                                // AB CD -> A CD AB CD (Top)
                                // System.out.println(analyzer.stackTagStatus);
                                LocalVariableNode[] lvs = storeToLocals(4);
                                loadLV(3, lvs);
                                loadLV(2, lvs);
                                loadLV(0, lvs);
                                analyzer.clearTopOfStackTagged();
                                loadLV(3, lvs);
                                loadLV(2, lvs);
                                loadLV(1, lvs);
                                loadLV(0, lvs);
                                freeLVs(lvs);
                            // System.out.println(analyzer.stackTagStatus);
                            } else {
                                // System.out.println("PRE " + analyzer.stack + analyzer.stackTagStatus);
                                if (topOfStack instanceof TaggedValue) {
                                    super.visitInsn(SWAP);
                                    super.visitInsn(POP);
                                }
                                // TA B -> TA B TA B
                                Type topType = getTypeForStackType(topOfStack);
                                int top = lvs.getTmpLV();
                                super.visitInsn(TaintUtils.IS_TMP_STORE);
                                super.visitVarInsn(topType.getOpcode(ISTORE), top);
                                // TA
                                super.visitInsn(DUP2);
                                // TA TA
                                super.visitVarInsn(topType.getOpcode(ILOAD), top);
                                // TA TA B
                                super.visitInsn(DUP_X2);
                                // AA BB AA BB
                                lvs.freeTmpLV(top);
                            // analyzer.setTopOfStackTagged();
                            // analyzer.stackTagStatus.set(analyzer.stackTagStatus.size() - 3, new TaggedValue(secondOnStack));
                            // System.out.println("POST " + analyzer.stack + analyzer.stackTagStatus);
                            }
                        } else {
                            if (nextDupCopiesTaint3) {
                                throw new UnsupportedOperationException();
                            } else // 0,!1,!2,!3
                            {
                                throw new UnsupportedOperationException();
                            }
                        }
                    }
                } else // !0
                {
                    if (nextDupCopiesTaint1) {
                        if (nextDupCopiesTaint2) {
                            if (nextDupCopiesTaint3) {
                            // !0, 1, 2, 3
                            } else {
                            // !0, 1,2,!3
                            }
                        }
                    } else // !0, !1
                    {
                        if (nextDupCopiesTaint2) {
                            if (nextDupCopiesTaint3) {
                                // !0, !1, 2, 3
                                // right here..
                                // T V T V -> V V T V T V
                                int v1 = lvs.getTmpLV();
                                super.visitVarInsn(ISTORE, v1);
                                int t1 = lvs.getTmpLV();
                                super.visitVarInsn(Configuration.TAINT_STORE_OPCODE, t1);
                                int v2 = lvs.getTmpLV();
                                super.visitVarInsn(ISTORE, v2);
                                int t2 = lvs.getTmpLV();
                                super.visitVarInsn(Configuration.TAINT_STORE_OPCODE, t2);
                                super.visitVarInsn(ILOAD, v2);
                                super.visitVarInsn(ILOAD, v1);
                                super.visitVarInsn(Configuration.TAINT_LOAD_OPCODE, t2);
                                super.visitVarInsn(ILOAD, v2);
                                super.visitVarInsn(Configuration.TAINT_LOAD_OPCODE, t1);
                                super.visitVarInsn(ILOAD, v1);
                                lvs.freeTmpLV(v1);
                                lvs.freeTmpLV(v2);
                                lvs.freeTmpLV(t1);
                                lvs.freeTmpLV(t2);
                                return;
                            } else {
                            // !0, !1, 2, !3
                            }
                        } else {
                            if (nextDupCopiesTaint3) {
                            // !0, !1, !2, 3
                            } else {
                                // !0, !1, !2, !3
                                if (getStackElementSize(getTopOfStackObject()) == 2) {
                                    if (analyzer.isTopOfStackTagged())
                                        throw new UnsupportedOperationException(Printer.OPCODES[opcode] + " " + analyzer.stackTagStatus + " - " + nextDupCopiesTaint0 + " " + nextDupCopiesTaint1 + " " + nextDupCopiesTaint2 + " " + nextDupCopiesTaint3);
                                    else {
                                        super.visitInsn(opcode);
                                        return;
                                    }
                                } else {
                                    if (analyzer.isTopOfStackTagged())
                                        throw new UnsupportedOperationException(Printer.OPCODES[opcode] + " " + analyzer.stackTagStatus + " - " + nextDupCopiesTaint0 + " " + nextDupCopiesTaint1 + " " + nextDupCopiesTaint2 + " " + nextDupCopiesTaint3);
                                    if (analyzer.stackTagStatus.get(analyzer.stack.size() - 2) instanceof TaggedValue)
                                        throw new UnsupportedOperationException(Printer.OPCODES[opcode] + " " + analyzer.stackTagStatus + " - " + nextDupCopiesTaint0 + " " + nextDupCopiesTaint1 + " " + nextDupCopiesTaint2 + " " + nextDupCopiesTaint3);
                                    super.visitInsn(opcode);
                                    return;
                                }
                            }
                        }
                    }
                    throw new UnsupportedOperationException(Printer.OPCODES[opcode] + " " + analyzer.stackTagStatus + " - " + nextDupCopiesTaint0 + " " + nextDupCopiesTaint1 + " " + nextDupCopiesTaint2 + " " + nextDupCopiesTaint3);
                }
            } else // DUP2, top of stack is double
            {
                topOfStack = analyzer.stackTagStatus.get(analyzer.stackTagStatus.size() - 2);
                // System.out.println(topOfStack + ""+secondOnStack);
                if (nextDupCopiesTaint0) {
                    if (nextDupCopiesTaint1) {
                        // TVV -> TVVTVV
                        Type topType = getTypeForStackType(topOfStack);
                        int top = lvs.getTmpLV();
                        super.visitInsn(TaintUtils.IS_TMP_STORE);
                        super.visitVarInsn(topType.getOpcode(ISTORE), top);
                        // T
                        super.visitInsn(DUP);
                        // TT
                        super.visitVarInsn(topType.getOpcode(ILOAD), top);
                        analyzer.setTopOfStackTagged();
                        // TTVV
                        super.visitInsn(DUP2_X1);
                        // TVVTVV
                        lvs.freeTmpLV(top);
                    } else {
                        // TVV -> TVV VV
                        super.visitInsn(DUP2);
                        analyzer.stackTagStatus.set(analyzer.stackTagStatus.size() - 2, analyzer.stack.get(analyzer.stack.size() - 2));
                    }
                } else {
                    if (nextDupCopiesTaint1) {
                        // TVV -> VVTVV
                        super.visitInsn(DUP2_X1);
                        analyzer.stackTagStatus.set(analyzer.stackTagStatus.size() - 5, analyzer.stack.get(analyzer.stack.size() - 5));
                    } else {
                        // VV -> VVVV
                        if (// should not be possible
                        topOfStack instanceof TaggedValue)
                            throw new UnsupportedOperationException();
                        super.visitInsn(DUP2);
                    }
                }
            // System.out.println("POST " + analyzer.stackTagStatus);
            }
            nextDupCopiesTaint0 = false;
            nextDupCopiesTaint1 = false;
            nextDupCopiesTaint2 = false;
            nextDupCopiesTaint3 = false;
            break;
        case Opcodes.DUP_X1:
            // new Exception().printStackTrace();
            if (nextDupCopiesTaint0) {
                if (!nextDupCopiesTaint1)
                    throw new UnsupportedOperationException();
                // System.out.println("DUP_X1 " + analyzer.stackTagStatus);
                topOfStack = analyzer.stackTagStatus.get(analyzer.stackTagStatus.size() - 1);
                if (topOfStack instanceof TaggedValue) {
                    // There is a 1 word element at the top of the stack, we want to dup
                    // it and it's taint to go one under so that it's
                    // T V X T V
                    Object underThisOne = analyzer.stackTagStatus.get(analyzer.stackTagStatus.size() - 3);
                    if (underThisOne instanceof TaggedValue) {
                        // X X T V -> T V X X T V
                        super.visitInsn(DUP2_X2);
                    } else {
                        // X T V -> T V X TV
                        super.visitInsn(DUP2_X1);
                    }
                } else {
                    Object underThisOne = analyzer.stackTagStatus.get(analyzer.stackTagStatus.size() - 2);
                    if (underThisOne instanceof TaggedValue) {
                        // X X V -> V X X V
                        super.visitInsn(DUP_X2);
                    } else {
                        // X V -> V X V
                        super.visitInsn(DUP_X1);
                    }
                }
            } else if (nextDupCopiesTaint1) {
                Object underThisOne = analyzer.stackTagStatus.get(analyzer.stackTagStatus.size() - 3);
                if (underThisOne instanceof TaggedValue) {
                    // T1 V1 T2 V2 -> V2 T1 V1 T2 V2
                    DUPN_XU(1, 3);
                    analyzer.stackTagStatus.set(analyzer.stack.size() - 5, ((TaggedValue) underThisOne).v);
                } else {
                    super.visitInsn(DUP_X2);
                    Object o = analyzer.stack.get(analyzer.stack.size() - 4);
                    if (o instanceof TaggedValue)
                        o = ((TaggedValue) o).v;
                    // need to make sure we clear the tag status on that dude!
                    analyzer.stackTagStatus.set(analyzer.stack.size() - 4, o);
                // System.out.println(analyzer.stack);
                // System.out.println(analyzer.stackTagStatus);
                }
            } else if (topCarriesTaint()) {
                // analyzer.stackTagStatus.set(analyzer.stack.size() - 4, o);
                throw new UnsupportedOperationException();
            } else if (analyzer.stackTagStatus.get(analyzer.stackTagStatus.size() - 2) instanceof TaggedValue) {
                super.visitInsn(DUP_X2);
            } else
                super.visitInsn(DUP_X1);
            nextDupCopiesTaint0 = false;
            nextDupCopiesTaint1 = false;
            nextDupCopiesTaint2 = false;
            nextDupCopiesTaint3 = false;
            // System.out.println("PSOT " + analyzer.stack + "; " + analyzer.stackTagStatus);
            break;
        case Opcodes.DUP_X2:
            // System.out.println("DUP_X2" + analyzer.stackTagStatus + nextDupCopiesTaint0 + nextDupCopiesTaint1);
            if (nextDupCopiesTaint0) {
                if (!nextDupCopiesTaint1) {
                    // 0, !1
                    // aka copythe taint under then delete it from top
                    System.out.println(analyzer.stackTagStatus);
                    throw new UnsupportedOperationException();
                } else {
                    // 0, 1
                    if (getStackElementSize(analyzer.stack.get(analyzer.stack.size() - 3)) == 2) {
                        // With long/double under
                        if (analyzer.stackTagStatus.get(analyzer.stackTagStatus.size() - 4) instanceof TaggedValue)
                            // Top 2 are tracked
                            DUPN_XU(2, 3);
                        else
                            // 2nd is not tracked.
                            DUPN_XU(2, 2);
                    } else {
                        // With 1word under
                        if (analyzer.stackTagStatus.get(analyzer.stackTagStatus.size() - 3) instanceof TaggedValue) {
                            if (analyzer.stackTagStatus.get(analyzer.stackTagStatus.size() - 5) instanceof TaggedValue)
                                DUPN_XU(2, 4);
                            else
                                DUPN_XU(2, 3);
                        } else {
                            // 2nd is not tracked.
                            if (analyzer.stackTagStatus.get(analyzer.stackTagStatus.size() - 4) instanceof TaggedValue)
                                DUPN_XU(2, 3);
                            else
                                super.visitInsn(DUP2_X2);
                        }
                    }
                }
            } else {
                if (nextDupCopiesTaint1) {
                    Object under = analyzer.stackTagStatus.get(analyzer.stackTagStatus.size() - 3);
                    if (under == Opcodes.TOP) {
                        // Two byte word
                        throw new UnsupportedOperationException();
                    } else {
                        if (under instanceof TaggedValue) {
                            Object twoUnder = analyzer.stackTagStatus.get(analyzer.stackTagStatus.size() - 5);
                            if (twoUnder instanceof TaggedValue) {
                                LocalVariableNode[] lvs = storeToLocals(6);
                                loadLV(0, lvs);
                                analyzer.clearTopOfStackTagged();
                                loadLV(5, lvs);
                                loadLV(4, lvs);
                                loadLV(3, lvs);
                                loadLV(2, lvs);
                                loadLV(1, lvs);
                                loadLV(0, lvs);
                                freeLVs(lvs);
                            } else {
                                // System.out.println("DUP_X2" + analyzer.stackTagStatus);
                                LocalVariableNode[] lvs = storeToLocals(5);
                                loadLV(0, lvs);
                                analyzer.clearTopOfStackTagged();
                                loadLV(4, lvs);
                                loadLV(3, lvs);
                                loadLV(2, lvs);
                                loadLV(1, lvs);
                                loadLV(0, lvs);
                                freeLVs(lvs);
                            }
                        } else {
                            // System.out.println(analyzer.stack);
                            Object twoUnder = analyzer.stackTagStatus.get(analyzer.stackTagStatus.size() - 4);
                            if (twoUnder instanceof TaggedValue) {
                                // 
                                DUPN_XU(1, 4);
                                // System.out.println(analyzer.stackTagStatus);
                                int off = analyzer.stack.size() - 6;
                                analyzer.stackTagStatus.set(off, analyzer.stack.get(off));
                            // throw new UnsupportedOperationException();
                            } else {
                                // TABTC -> CATB
                                DUPN_XU(1, 3);
                                int off = analyzer.stack.size() - 5;
                                analyzer.stackTagStatus.set(off, analyzer.stack.get(off));
                            }
                        }
                    }
                } else {
                    // Dont want to copy any taint
                    if (topCarriesTaint()) {
                        // Top has a tag, but we don't want to keep it
                        if (getStackElementSize(analyzer.stack.get(analyzer.stack.size() - 2)) == 2) {
                            // With long/double under
                            if (analyzer.stackTagStatus.get(analyzer.stackTagStatus.size() - 3) instanceof TaggedValue)
                                // Top 2 are tracked
                                DUPN_XU(1, 4);
                            else
                                // 2nd is not tracked.
                                DUPN_XU(1, 3);
                        } else {
                            // With 1word under
                            if (analyzer.stackTagStatus.get(analyzer.stackTagStatus.size() - 3) instanceof TaggedValue) {
                                if (analyzer.stackTagStatus.get(analyzer.stackTagStatus.size() - 5) instanceof TaggedValue)
                                    DUPN_XU(1, 5);
                                else
                                    DUPN_XU(1, 4);
                            } else {
                                // 2nd is not tracked.
                                if (analyzer.stackTagStatus.get(analyzer.stackTagStatus.size() - 4) instanceof TaggedValue) {
                                    DUPN_XU(1, 4);
                                } else
                                    DUPN_XU(1, 3);
                            }
                        }
                    } else {
                        // What's under us?
                        if (analyzer.stack.get(analyzer.stack.size() - 2) == Opcodes.TOP) {
                            if (analyzer.stackTagStatus.get(analyzer.stackTagStatus.size() - 3) instanceof TaggedValue) {
                                LocalVariableNode[] d = storeToLocals(3);
                                loadLV(0, d);
                                loadLV(2, d);
                                loadLV(1, d);
                                loadLV(0, d);
                                freeLVs(d);
                            } else
                                super.visitInsn(DUP_X2);
                        } else {
                            // 1 word under us. is it tagged?
                            if (analyzer.stackTagStatus.get(analyzer.stackTagStatus.size() - 2) instanceof TaggedValue) {
                                if (analyzer.stackTagStatus.get(analyzer.stackTagStatus.size() - 4) instanceof TaggedValue) {
                                    throw new UnsupportedOperationException();
                                } else {
                                    DUPN_XU(1, 3);
                                }
                            } else if (analyzer.stackTagStatus.get(analyzer.stackTagStatus.size() - 3) instanceof TaggedValue) {
                                throw new UnsupportedOperationException();
                            } else
                                super.visitInsn(DUP_X2);
                        }
                    }
                }
            }
            // System.out.println("post DUP_X2" + analyzer.stackTagStatus);
            nextDupCopiesTaint0 = false;
            nextDupCopiesTaint1 = false;
            nextDupCopiesTaint2 = false;
            nextDupCopiesTaint3 = false;
            break;
        case Opcodes.DUP2_X1:
            // ABC -> BCABC (0 1 2 3 4)
            if (nextDupCopiesTaint0) {
                if (nextDupCopiesTaint1) {
                    if (nextDupCopiesTaint2) {
                        if (nextDupCopiesTaint3) {
                            // 0, 1, 2, 3
                            throw new UnsupportedOperationException();
                        } else {
                            // 0, 1, 2, !3
                            throw new UnsupportedOperationException();
                        }
                    } else {
                        if (nextDupCopiesTaint3) {
                            // 0, 1, !2, 3
                            throw new UnsupportedOperationException();
                        } else {
                            // 0,1,!2,!3
                            // ATBTC -> TBTCABC
                            // 2 word?
                            topOfStack = analyzer.stackTagStatus.get(analyzer.stackTagStatus.size() - 1);
                            if (getStackElementSize(topOfStack) == 2) {
                                topOfStack = analyzer.stackTagStatus.get(analyzer.stackTagStatus.size() - 2);
                                if (!(topOfStack instanceof TaggedValue))
                                    throw new UnsupportedOperationException("Top must be tagged for this");
                                Object secondOnStack = analyzer.stackTagStatus.get(analyzer.stackTagStatus.size() - 4);
                                if (secondOnStack instanceof TaggedValue) {
                                    // TATBB -> TBBTATBB
                                    throw new UnsupportedOperationException();
                                } else {
                                    // ATBB -> TBBATBB
                                    DUPN_XU(2, 1);
                                }
                            // throw new UnsupportedOperationException();
                            // System.out.println(analyzer.stackTagStatus);
                            } else {
                                throw new UnsupportedOperationException();
                            }
                        }
                    }
                } else {
                    if (nextDupCopiesTaint2) {
                        if (nextDupCopiesTaint3) {
                            // !0, !1, 2, 3
                            throw new UnsupportedOperationException();
                        } else {
                            // !0, !1, 2, !3
                            throw new UnsupportedOperationException();
                        }
                    } else {
                        if (nextDupCopiesTaint3) {
                            if (getTopOfStackType().getSize() == 2) {
                                // 0 !1 !2 3
                                // System.out.println(analyzer.stack);
                                LocalVariableNode[] d = storeToLocals(3);
                                // System.out.println(analyzer.stackTagStatus);
                                loadLV(1, d);
                                loadLV(0, d);
                                // loadLV(3, d);
                                loadLV(2, d);
                                loadLV(1, d);
                                loadLV(0, d);
                                freeLVs(d);
                            // System.out.println(nextDupCopiesTaint0
                            // +","+nextDupCopiesTaint1+","+nextDupCopiesTaint2+","+nextDupCopiesTaint3);
                            // System.out.println(analyzer.stackTagStatus);
                            // throw new UnsupportedOperationException();
                            } else {
                                // !0, !1, !2, 3
                                // System.out.println(analyzer.stackTagStatus);
                                LocalVariableNode[] d = storeToLocals(4);
                                // System.out.println(analyzer.stackTagStatus);
                                loadLV(2, d);
                                loadLV(0, d);
                                analyzer.clearTopOfStackTagged();
                                loadLV(3, d);
                                loadLV(2, d);
                                loadLV(1, d);
                                loadLV(0, d);
                                freeLVs(d);
                            // System.out.println(nextDupCopiesTaint0
                            // +","+nextDupCopiesTaint1+","+nextDupCopiesTaint2+","+nextDupCopiesTaint3);
                            // System.out.println(analyzer.stackTagStatus);
                            // throw new UnsupportedOperationException();
                            }
                        } else {
                            // DUP2_X1
                            if (topCarriesTaint()) {
                                if (analyzer.stackTagStatus.get(analyzer.stackTagStatus.size() - 3) instanceof TaggedValue) {
                                } else {
                                    // System.out.println(analyzer.stackTagStatus);
                                    super.visitInsn(SWAP);
                                    super.visitInsn(POP);
                                    analyzer.clearTopOfStackTagged();
                                    super.visitInsn(opcode);
                                    // throw new UnsupportedOperationException();
                                    return;
                                }
                            }
                            System.out.println(analyzer.stackTagStatus);
                            throw new UnsupportedOperationException();
                        }
                    }
                }
            } else {
                if (nextDupCopiesTaint1) {
                    if (nextDupCopiesTaint2) {
                        if (nextDupCopiesTaint3) {
                            // !0, 1, 2, 3
                            throw new UnsupportedOperationException();
                        } else {
                            // !0, 1, 2, !3
                            throw new UnsupportedOperationException();
                        }
                    } else {
                        if (nextDupCopiesTaint3) {
                            // !0, 1, !2, 3
                            throw new UnsupportedOperationException();
                        } else {
                            // !0,1,!2,!3
                            topOfStack = analyzer.stackTagStatus.get(analyzer.stackTagStatus.size() - 1);
                            if (getStackElementSize(topOfStack) == 2) {
                                // A TVV -> VV A T VV
                                super.visitInsn(DUP2_X2);
                                int idx = analyzer.stack.size() - 6;
                                analyzer.stackTagStatus.set(idx, analyzer.stack.get(idx));
                            } else {
                                // System.out.println(analyzer.stackTagStatus);
                                LocalVariableNode[] d = storeToLocals(4);
                                // System.out.println(analyzer.stackTagStatus);
                                loadLV(2, d);
                                loadLV(1, d);
                                loadLV(0, d);
                                loadLV(3, d);
                                loadLV(2, d);
                                loadLV(0, d);
                                analyzer.clearTopOfStackTagged();
                                freeLVs(d);
                            // System.out.println(nextDupCopiesTaint0 +","+nextDupCopiesTaint1+","+nextDupCopiesTaint2+","+nextDupCopiesTaint3);
                            // System.out.println(analyzer.stackTagStatus);
                            // throw new UnsupportedOperationException();
                            }
                        }
                    }
                } else {
                    if (nextDupCopiesTaint2) {
                        if (nextDupCopiesTaint3) {
                            // !0, !1, 2, 3
                            throw new UnsupportedOperationException();
                        } else {
                            // !0, !1, 2, !3
                            throw new UnsupportedOperationException();
                        }
                    } else {
                        if (nextDupCopiesTaint3) {
                            // !0, !1, !2, 3
                            if (getTopOfStackType().getSize() == 2) {
                                // System.out.println(analyzer.stackTagStatus);
                                LocalVariableNode[] d = storeToLocals(3);
                                // loadLV(2, d);
                                loadLV(0, d);
                                analyzer.clearTopOfStackTagged();
                                // loadLV(3, d);
                                loadLV(2, d);
                                loadLV(1, d);
                                loadLV(0, d);
                                freeLVs(d);
                            // System.out.println(nextDupCopiesTaint0
                            // +","+nextDupCopiesTaint1+","+nextDupCopiesTaint2+","+nextDupCopiesTaint3);
                            // System.out.println(analyzer.stackTagStatus);
                            // throw new UnsupportedOperationException();
                            } else {
                                // System.out.println(analyzer.stackTagStatus);
                                LocalVariableNode[] d = storeToLocals(4);
                                loadLV(2, d);
                                loadLV(0, d);
                                analyzer.clearTopOfStackTagged();
                                loadLV(3, d);
                                loadLV(2, d);
                                loadLV(1, d);
                                loadLV(0, d);
                                freeLVs(d);
                            // System.out.println(nextDupCopiesTaint0
                            // +","+nextDupCopiesTaint1+","+nextDupCopiesTaint2+","+nextDupCopiesTaint3);
                            // System.out.println(analyzer.stackTagStatus);
                            // throw new UnsupportedOperationException();
                            }
                        } else {
                            // !0,!1,!2,!3
                            if (analyzer.stackTagStatus.get(analyzer.stackTagStatus.size() - 1) instanceof TaggedValue)
                                throw new UnsupportedOperationException();
                            else if (analyzer.stackTagStatus.get(analyzer.stackTagStatus.size() - 2) instanceof TaggedValue)
                                throw new UnsupportedOperationException();
                            else if (analyzer.stackTagStatus.get(analyzer.stackTagStatus.size() - 3) instanceof TaggedValue) {
                                super.visitInsn(DUP2_X2);
                                return;
                            }
                            super.visitInsn(opcode);
                        }
                    }
                }
            }
            // // Z A B OR Z Z' A B?
            // if (getStackElementSize(analyzer.stack.get(analyzer.stack.size() - 1)) == 2) {
            // // Have two-word el + 1 word taint on top
            // if (analyzer.stackTagStatus.get(analyzer.stackTagStatus.size() - 4) instanceof TaggedValue) {
            // // Dup the top three words to be under the 2 words
            // // beneath them
            // DUPN_XU(2, 2);
            // } else {
            // // Dup the top three words to be under the word beneath
            // // them
            // DUPN_XU(2, 1);
            // }
            // } else {
            // if (analyzer.stackTagStatus.get(analyzer.stackTagStatus.size() - 3) instanceof TaggedValue) {
            // // Both this and the guy under are tracked
            // if (analyzer.stackTagStatus.get(analyzer.stackTagStatus.size() - 5) instanceof TaggedValue) {
            // DUPN_XU(4, 2);
            // } else
            // DUPN_XU(4, 1);
            // } else {
            // // Top is tracked, guy under isn't
            // if (analyzer.stackTagStatus.get(analyzer.stackTagStatus.size() - 4) instanceof TaggedValue) {
            // DUPN_XU(3, 2);
            // } else
            // DUPN_XU(3, 1);
            // 
            // }
            // }
            // 
            // if(topCarriesTaint())
            // {
            // if (getStackElementSize(analyzer.stack.get(analyzer.stack.size() - 1)) == 2) {
            // if(analyzer.stackTagStatus.get(analyzer.stackTagStatus.size() - 4) instanceof TaggedValue)
            // {
            // //Top is 2 words, then tag, then tagged value. Don't want to copy the tag under htough
            // DUPN_XU(2, 3);
            // }
            // else
            // {
            // //Top is 2 words tagged, then regular value
            // super.visitInsn(DUP2_X2);
            // }
            // }
            // else
            // throw new UnsupportedOperationException();
            // }
            // else if(analyzer.stackTagStatus.get(analyzer.stackTagStatus.size() - 2) instanceof TaggedValue)
            // {
            // throw new UnsupportedOperationException();
            // }
            // else if(analyzer.stackTagStatus.get(analyzer.stackTagStatus.size() - 3) instanceof TaggedValue)
            // {
            // throw new UnsupportedOperationException();
            // }
            // else
            // super.visitInsn(DUP2_X1);
            nextDupCopiesTaint0 = false;
            nextDupCopiesTaint1 = false;
            nextDupCopiesTaint2 = false;
            nextDupCopiesTaint3 = false;
            break;
        case Opcodes.DUP2_X2:
            if (nextDupCopiesTaint0) {
                if (nextDupCopiesTaint1) {
                    if (nextDupCopiesTaint2) {
                        if (nextDupCopiesTaint3) {
                            // 0, 1, 2, 3
                            throw new UnsupportedOperationException();
                        } else {
                            // 0, 1, 2, !3
                            throw new UnsupportedOperationException();
                        }
                    } else {
                        if (nextDupCopiesTaint3) {
                            // 0, 1, !2, 3
                            throw new UnsupportedOperationException();
                        } else {
                            // System.out.println("DUP2_X2 "+ analyzer.stackTagStatus);
                            if (getStackElementSize(getTopOfStackObject()) == 2) {
                                // ?A?BTC -> TC?A?BTC
                                topOfStack = analyzer.stackTagStatus.get(analyzer.stackTagStatus.size() - 2);
                                // System.out.println(topOfStack);
                                Object second = analyzer.stackTagStatus.get(analyzer.stackTagStatus.size() - 4);
                                if (getStackElementSize(second) == 2) {
                                    // ?AATC -> TC?AAC
                                    throw new UnsupportedOperationException();
                                } else {
                                    if (second instanceof TaggedValue) {
                                        Object third = analyzer.stackTagStatus.get(analyzer.stackTagStatus.size() - 6);
                                        if (third instanceof TaggedValue) {
                                            LocalVariableNode[] d = storeToLocals(6);
                                            loadLV(1, d);
                                            loadLV(0, d);
                                            loadLV(5, d);
                                            loadLV(4, d);
                                            loadLV(3, d);
                                            loadLV(2, d);
                                            loadLV(0, d);
                                            analyzer.clearTopOfStackTagged();
                                            freeLVs(d);
                                        } else {
                                            // ATBTC -> TCATBTC
                                            DUPN_XU(2, 3);
                                        }
                                    // System.out.println(analyzer.stackTagStatus);
                                    // throw new UnsupportedOperationException();
                                    } else {
                                        Object third = analyzer.stackTagStatus.get(analyzer.stackTagStatus.size() - 5);
                                        if (third instanceof TaggedValue) {
                                            // ATBTC -> TCATBTC
                                            DUPN_XU(2, 3);
                                        } else
                                            throw new UnsupportedOperationException();
                                    // System.out.println(analyzer.stackTagStatus);
                                    // throw new UnsupportedOperationException();
                                    }
                                }
                            } else
                                throw new UnsupportedOperationException();
                        }
                    }
                } else {
                    if (nextDupCopiesTaint2) {
                        if (nextDupCopiesTaint3) {
                            // !0, !1, 2, 3
                            throw new UnsupportedOperationException();
                        } else {
                            // !0, !1, 2, !3
                            throw new UnsupportedOperationException();
                        }
                    } else {
                        if (nextDupCopiesTaint3) {
                            // !0, !1, !2, 3
                            throw new UnsupportedOperationException();
                        } else {
                            // !0,!1,!2,!3
                            throw new UnsupportedOperationException();
                        }
                    }
                }
            } else {
                if (nextDupCopiesTaint1) {
                    if (nextDupCopiesTaint2) {
                        if (nextDupCopiesTaint3) {
                            // !0, 1, 2, 3
                            throw new UnsupportedOperationException();
                        } else {
                            // !0, 1, 2, !3
                            throw new UnsupportedOperationException();
                        }
                    } else {
                        if (nextDupCopiesTaint3) {
                            // !0, 1, !2, 3
                            throw new UnsupportedOperationException();
                        } else {
                            // !0,1,!2,!3
                            if (getStackElementSize(getTopOfStackObject()) == 2) {
                                if (analyzer.stackTagStatus.get(analyzer.stack.size() - 2) instanceof TaggedValue) {
                                    // top 2 words, tagged
                                    if (getStackElementSize(analyzer.stack.get(analyzer.stack.size() - 4)) == 2) {
                                        throw new UnsupportedOperationException();
                                    } else {
                                        // ABTCC -> CCABTCC
                                        Object second = analyzer.stackTagStatus.get(analyzer.stack.size() - 4);
                                        if (second instanceof TaggedValue) {
                                            // System.out.println("D2X2" + analyzer.stackTagStatus);
                                            LocalVariableNode[] d = storeToLocals(6);
                                            loadLV(0, d);
                                            analyzer.clearTopOfStackTagged();
                                            loadLV(5, d);
                                            loadLV(4, d);
                                            loadLV(3, d);
                                            loadLV(2, d);
                                            loadLV(1, d);
                                            loadLV(0, d);
                                            freeLVs(d);
                                        // System.out.println("D2X2" + analyzer.stackTagStatus);
                                        // throw new UnsupportedOperationException();
                                        } else {
                                            Object third = analyzer.stackTagStatus.get(analyzer.stack.size() - 5);
                                            if (third instanceof TaggedValue) {
                                                DUPN_XU(1, 4);
                                                analyzer.stackTagStatus.set(analyzer.stack.size() - 8, analyzer.stack.get(analyzer.stack.size() - 8));
                                            } else {
                                                throw new UnsupportedOperationException();
                                            }
                                        }
                                    }
                                } else {
                                    throw new UnsupportedOperationException();
                                }
                            } else {
                                throw new UnsupportedOperationException();
                            }
                        }
                    }
                } else {
                    if (nextDupCopiesTaint2) {
                        if (nextDupCopiesTaint3) {
                            // !0, !1, 2, 3
                            throw new UnsupportedOperationException();
                        } else {
                            // !0, !1, 2, !3
                            throw new UnsupportedOperationException();
                        }
                    } else {
                        if (nextDupCopiesTaint3) {
                            // !0, !1, !2, 3
                            throw new UnsupportedOperationException();
                        } else {
                            // !0,!1,!2,!3
                            if (analyzer.stackTagStatus.get(analyzer.stackTagStatus.size() - 2) instanceof TaggedValue) {
                                throw new UnsupportedOperationException();
                            } else if (analyzer.stackTagStatus.get(analyzer.stackTagStatus.size() - 3) instanceof TaggedValue) {
                                throw new UnsupportedOperationException();
                            } else if (analyzer.stackTagStatus.get(analyzer.stackTagStatus.size() - 4) instanceof TaggedValue) {
                                DUPN_XU(2, 2);
                            } else {
                                super.visitInsn(DUP2_X2);
                            }
                        }
                    }
                }
            }
            // if(nextDupCopiesTaint0 || nextDupCopiesTaint1)
            // {
            // throw new UnsupportedOperationException();
            // }
            // else if(topCarriesTaint())
            // {
            // throw new UnsupportedOperationException();
            // }
            // else if(analyzer.stackTagStatus.get(analyzer.stackTagStatus.size() - 2) instanceof TaggedValue)
            // {
            // throw new UnsupportedOperationException();
            // }
            // else if(analyzer.stackTagStatus.get(analyzer.stackTagStatus.size() - 3) instanceof TaggedValue)
            // {
            // throw new UnsupportedOperationException();
            // }
            // else
            // super.visitInsn(DUP2_X2);
            nextDupCopiesTaint0 = false;
            nextDupCopiesTaint1 = false;
            nextDupCopiesTaint2 = false;
            nextDupCopiesTaint3 = false;
            break;
        case Opcodes.SWAP:
            if (topCarriesTaint() || analyzer.stackTagStatus.get(analyzer.stackTagStatus.size() - 1) instanceof TaggedValue) {
                if (nextLoadisTracked) {
                    if (analyzer.stackTagStatus.get(analyzer.stackTagStatus.size() - 3) instanceof TaggedValue) {
                        super.visitInsn(DUP2_X2);
                        super.visitInsn(POP2);
                    } else {
                        super.visitInsn(DUP2_X1);
                        super.visitInsn(POP2);
                    }
                } else {
                    super.visitInsn(DUP2_X1);
                    super.visitInsn(POP2);
                }
            } else if (analyzer.stackTagStatus.get(analyzer.stackTagStatus.size() - 2) instanceof TaggedValue) {
                // Top has no tag, second does
                super.visitInsn(DUP_X2);
                super.visitInsn(POP);
            } else
                super.visitInsn(SWAP);
            nextLoadisTracked = false;
            break;
        case Opcodes.FADD:
        case Opcodes.FREM:
        case Opcodes.FSUB:
        case Opcodes.FMUL:
        case Opcodes.FDIV:
            {
                if (!topCarriesTaint()) {
                    super.visitInsn(opcode);
                    break;
                } else {
                    Configuration.taintTagFactory.stackOp(opcode, mv, lvs, this);
                    analyzer.setTopOfStackTagged();
                }
            }
            break;
        case Opcodes.IADD:
        case Opcodes.ISUB:
        case Opcodes.IMUL:
        case Opcodes.IDIV:
        case Opcodes.IREM:
        case Opcodes.ISHL:
        case Opcodes.ISHR:
        case Opcodes.IUSHR:
        case Opcodes.IOR:
        case Opcodes.IAND:
        case Opcodes.IXOR:
            // System.out.println(Printer.OPCODES[opcode] + " "+ analyzer.stackTagStatus);
            if (!topCarriesTaint()) {
                super.visitInsn(opcode);
                break;
            } else {
                Configuration.taintTagFactory.stackOp(opcode, mv, lvs, this);
                analyzer.setTopOfStackTagged();
            }
            break;
        case Opcodes.DADD:
        case Opcodes.DSUB:
        case Opcodes.DMUL:
        case Opcodes.DDIV:
        case Opcodes.DREM:
            {
                if (!topCarriesTaint()) {
                    super.visitInsn(opcode);
                    break;
                } else {
                    Configuration.taintTagFactory.stackOp(opcode, mv, lvs, this);
                    analyzer.setTopOfStackTagged();
                }
            }
            break;
        case Opcodes.LSHL:
        case Opcodes.LUSHR:
        case Opcodes.LSHR:
            if (!topCarriesTaint()) {
                super.visitInsn(opcode);
                break;
            } else {
                Configuration.taintTagFactory.stackOp(opcode, mv, lvs, this);
                analyzer.setTopOfStackTagged();
            }
            break;
        case Opcodes.LSUB:
        case Opcodes.LMUL:
        case Opcodes.LADD:
        case Opcodes.LDIV:
        case Opcodes.LREM:
        case Opcodes.LAND:
        case Opcodes.LOR:
        case Opcodes.LXOR:
            if (!topCarriesTaint()) {
                super.visitInsn(opcode);
                break;
            } else {
                Configuration.taintTagFactory.stackOp(opcode, mv, lvs, this);
                analyzer.setTopOfStackTagged();
            }
            break;
        case Opcodes.INEG:
        case Opcodes.FNEG:
        case Opcodes.LNEG:
        case Opcodes.DNEG:
        case Opcodes.I2L:
        case Opcodes.I2F:
        case Opcodes.I2D:
        case Opcodes.L2I:
        case Opcodes.L2F:
        case Opcodes.L2D:
        case Opcodes.F2I:
        case Opcodes.F2L:
        case Opcodes.F2D:
        case Opcodes.D2I:
        case Opcodes.D2L:
        case Opcodes.D2F:
        case Opcodes.I2B:
        case Opcodes.I2C:
        case Opcodes.I2S:
            Configuration.taintTagFactory.stackOp(opcode, mv, lvs, this);
            nextLoadisTracked = false;
            break;
        case Opcodes.LCMP:
        case Opcodes.DCMPL:
        case Opcodes.DCMPG:
        case Opcodes.FCMPL:
        case Opcodes.FCMPG:
            // System.out.println(Printer.OPCODES[opcode] + analyzer.stack + analyzer.stackTagStatus);
            if (!topCarriesTaint()) {
                super.visitInsn(opcode);
                break;
            } else {
                Configuration.taintTagFactory.stackOp(opcode, mv, lvs, this);
                analyzer.setTopOfStackTagged();
            }
            break;
        case Opcodes.DRETURN:
        case Opcodes.LRETURN:
            int retIdx = lvs.getPreAllocedReturnTypeVar(newReturnType);
            super.visitVarInsn(ALOAD, retIdx);
            super.visitInsn(DUP_X2);
            super.visitInsn(POP);
            super.visitFieldInsn(PUTFIELD, newReturnType.getInternalName(), "val", originalMethodReturnType.getDescriptor());
            super.visitVarInsn(ALOAD, retIdx);
            super.visitInsn(SWAP);
            super.visitFieldInsn(PUTFIELD, newReturnType.getInternalName(), "taint", Configuration.TAINT_TAG_DESC);
            super.visitVarInsn(ALOAD, retIdx);
            Configuration.taintTagFactory.stackOp(opcode, mv, lvs, this);
            super.visitInsn(ARETURN);
            break;
        case Opcodes.IRETURN:
        case Opcodes.FRETURN:
            // super.visitMethodInsn(INVOKESTATIC, TaintUtils.getContainerReturnType(originalMethodReturnType).getInternalName(), "valueOf", "(I" + originalMethodReturnType.getDescriptor() + ")"
            // + TaintUtils.getContainerReturnType(originalMethodReturnType).getDescriptor());
            retIdx = lvs.getPreAllocedReturnTypeVar(newReturnType);
            super.visitVarInsn(ALOAD, retIdx);
            super.visitInsn(SWAP);
            super.visitFieldInsn(PUTFIELD, newReturnType.getInternalName(), "val", originalMethodReturnType.getDescriptor());
            super.visitVarInsn(ALOAD, retIdx);
            super.visitInsn(SWAP);
            super.visitFieldInsn(PUTFIELD, newReturnType.getInternalName(), "taint", Configuration.TAINT_TAG_DESC);
            super.visitVarInsn(ALOAD, retIdx);
            Configuration.taintTagFactory.stackOp(opcode, mv, lvs, this);
            super.visitInsn(ARETURN);
            break;
        case Opcodes.ARETURN:
            Type onStack = getTopOfStackType();
            if (originalMethodReturnType.getSort() == Type.ARRAY) {
                if (onStack.getSort() == Type.OBJECT) {
                    super.visitInsn(opcode);
                    return;
                } else if (originalMethodReturnType.getDimensions() > 1 && (onStack.getSort() != Type.ARRAY || onStack.getElementType().getSort() == Type.OBJECT)) {
                    super.visitInsn(opcode);
                    return;
                }
                switch(originalMethodReturnType.getElementType().getSort()) {
                    case Type.INT:
                    case Type.LONG:
                    case Type.BOOLEAN:
                    case Type.BYTE:
                    case Type.CHAR:
                    case Type.DOUBLE:
                    case Type.FLOAT:
                    case Type.SHORT:
                        registerTaintedArray();
                        Configuration.taintTagFactory.stackOp(opcode, mv, lvs, this);
                        super.visitInsn(ARETURN);
                        break;
                    default:
                        Configuration.taintTagFactory.stackOp(opcode, mv, lvs, this);
                        super.visitInsn(opcode);
                }
            } else if (onStack.getSort() == Type.ARRAY && onStack.getDimensions() == 1 && onStack.getElementType().getSort() != Type.OBJECT) {
                registerTaintedArray();
                Configuration.taintTagFactory.stackOp(opcode, mv, lvs, this);
                super.visitInsn(opcode);
            } else {
                Configuration.taintTagFactory.stackOp(opcode, mv, lvs, this);
                super.visitInsn(opcode);
            }
            break;
        case Opcodes.RETURN:
            Configuration.taintTagFactory.stackOp(opcode, mv, lvs, this);
            super.visitInsn(opcode);
            break;
        case Opcodes.ARRAYLENGTH:
            if (nextLoadisTracked) {
                Configuration.taintTagFactory.stackOp(opcode, mv, lvs, this);
                analyzer.setTopOfStackTagged();
                nextLoadisTracked = false;
            } else
                super.visitInsn(opcode);
            break;
        case Opcodes.ATHROW:
            if (TaintUtils.DEBUG_FRAMES)
                System.out.println("ATHROW " + analyzer.stack);
            super.visitInsn(opcode);
            break;
        case Opcodes.MONITORENTER:
        case Opcodes.MONITOREXIT:
            // You can have a monitor on an array type. If it's a primitive array type, pop the taint off!
            // else if(getTopOfStackObject().equals("java/lang/Object"))
            // {
            // //never allow monitor to occur on a multid type
            // super.visitMethodInsn(Opcodes.INVOKESTATIC, Type.getInternalName(MultiDTaintedArray.class), "unbox1D", "(Ljava/lang/Object;)Ljava/lang/Object;", false);
            // }
            super.visitInsn(opcode);
            break;
        case TaintUtils.FOLLOWED_BY_FRAME:
            super.visitInsn(opcode);
            break;
        default:
            super.visitInsn(opcode);
            throw new IllegalArgumentException();
    }
}
Also used : TaggedValue(edu.columbia.cs.psl.phosphor.instrumenter.analyzer.TaggedValue) LocalVariableNode(org.objectweb.asm.tree.LocalVariableNode) ControlTaintTagStack(edu.columbia.cs.psl.phosphor.struct.ControlTaintTagStack) Type(org.objectweb.asm.Type)

Example 24 with LocalVariableNode

use of org.objectweb.asm.tree.LocalVariableNode 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 25 with LocalVariableNode

use of org.objectweb.asm.tree.LocalVariableNode in project phosphor by gmu-swe.

the class LocalVariableManager method remapLocal.

@Override
public void remapLocal(int local, Type type) {
    Label lbl = new Label();
    super.visitLabel(lbl);
    curLocalIdxToLVNode.get(local).end = new LabelNode(lbl);
    super.remapLocal(local, type);
    LocalVariableNode newLVN = new LocalVariableNode("phosphorShadowLV" + createdLVIdx, type.getDescriptor(), null, new LabelNode(lbl), new LabelNode(end), local);
    createdLVs.add(newLVN);
    curLocalIdxToLVNode.put(local, newLVN);
    createdLVIdx++;
}
Also used : LabelNode(org.objectweb.asm.tree.LabelNode) Label(org.objectweb.asm.Label) LocalVariableNode(org.objectweb.asm.tree.LocalVariableNode)

Aggregations

LocalVariableNode (org.objectweb.asm.tree.LocalVariableNode)41 Label (org.objectweb.asm.Label)11 MethodNode (org.objectweb.asm.tree.MethodNode)9 Type (org.objectweb.asm.Type)8 LabelNode (org.objectweb.asm.tree.LabelNode)8 VarInsnNode (org.objectweb.asm.tree.VarInsnNode)8 FieldInsnNode (org.objectweb.asm.tree.FieldInsnNode)6 IincInsnNode (org.objectweb.asm.tree.IincInsnNode)6 GeneratorAdapter (org.objectweb.asm.commons.GeneratorAdapter)5 AbstractInsnNode (org.objectweb.asm.tree.AbstractInsnNode)5 InsnList (org.objectweb.asm.tree.InsnList)5 MethodInsnNode (org.objectweb.asm.tree.MethodInsnNode)5 ClassNode (org.objectweb.asm.tree.ClassNode)4 HashMap (java.util.HashMap)3 Iterator (java.util.Iterator)3 FieldNode (org.objectweb.asm.tree.FieldNode)3 FrameNode (org.objectweb.asm.tree.FrameNode)3 TryCatchBlockNode (org.objectweb.asm.tree.TryCatchBlockNode)3 NeverNullArgAnalyzerAdapter (edu.columbia.cs.psl.phosphor.instrumenter.analyzer.NeverNullArgAnalyzerAdapter)2 ControlTaintTagStack (edu.columbia.cs.psl.phosphor.struct.ControlTaintTagStack)2