Search in sources :

Example 11 with LocalVariableNode

use of org.objectweb.asm.tree.LocalVariableNode in project openj9 by eclipse.

the class ClassFileCompare method compareLocalVariables.

private void compareLocalVariables(final MethodNode method1, final MethodNode method2) {
    /*
		 * J9 may strip LocalVariableTable and LocalVariableTypeTable attributes.
		 */
    if (!shouldCompareDebugInfo) {
        return;
    }
    if (nullCheck(method1.localVariables, method2.localVariables, "Local variables (" + method1.name + ")")) {
        return;
    }
    /*
		 * Copy and sort local variables by scope and index
		 */
    @SuppressWarnings("unchecked") List<LocalVariableNode> localVars1 = new ArrayList<>(method1.localVariables);
    @SuppressWarnings("unchecked") List<LocalVariableNode> localVars2 = new ArrayList<>(method2.localVariables);
    Collections.sort(localVars1, localVariableComparatorFor(method1));
    Collections.sort(localVars2, localVariableComparatorFor(method2));
    /*
		 * Compare local variables
		 */
    if (localVars1.size() != localVars2.size()) {
        reportDifference("Local variables (" + method1.name + ") differ: " + localVars1.size() + ", " + localVars2.size());
    } else {
        Iterator<LocalVariableNode> iter = localVars1.iterator();
        for (LocalVariableNode localVar2 : localVars2) {
            LocalVariableNode localVar1 = iter.next();
            compare(localVar1.name, localVar2.name, "Local variables (" + method1.name + ") name");
            compare(localVar1.desc, localVar2.desc, "Local variables (" + method1.name + ") descriptor");
            compare(localVar1.signature, localVar2.signature, "Local variables (" + method1.name + ") generic signature");
            compare(localVar1.index, localVar2.index, "Local variables (" + method1.name + ") indexes", false);
            compare(method1, localVar1.start, method2, localVar2.start, "Local variables scope (" + method1.name + ") starts");
            compare(method1, localVar1.end, method2, localVar2.end, "Local variables scope (" + method1.name + ") ends");
        }
    }
}
Also used : ArrayList(java.util.ArrayList) LocalVariableNode(org.objectweb.asm.tree.LocalVariableNode)

Example 12 with LocalVariableNode

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

the class TaintTrackingClassVisitor method generateNativeWrapper.

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

Example 13 with LocalVariableNode

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

the class LocalVariableManager method visitLocalVariable.

@Override
public void visitLocalVariable(String name, String desc, String signature, Label start, Label end, int index) {
    super.visitLocalVariable(name, desc, signature, start, end, index);
    if (!createdLVs.isEmpty()) {
        if (!endVisited) {
            super.visitLabel(this.end);
            endVisited = true;
        }
        for (LocalVariableNode n : createdLVs) {
            uninstMV.visitLocalVariable(n.name, n.desc, n.signature, n.start.getLabel(), n.end.getLabel(), n.index);
        }
        createdLVs.clear();
    }
}
Also used : LocalVariableNode(org.objectweb.asm.tree.LocalVariableNode)

Example 14 with LocalVariableNode

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

the class LocalVariableManager method newShadowLV.

// HashSet<String> usedShadowNames = new HashSet<>();
public int newShadowLV(Type type, int shadows) {
    int idx = super.newLocal(type);
    Label lbl = new Label();
    super.visitLabel(lbl);
    String shadowName = null;
    if (primitiveArrayFixer != null)
        for (Object o : primitiveArrayFixer.mn.localVariables) {
            LocalVariableNode lv = (LocalVariableNode) o;
            int id = remap(lv.index + (lv.index < lastArg - extraLVsInArg ? 0 : extraLVsInArg), Type.getType(lv.desc));
            if (id == shadows) {
                shadowName = lv.name + "$$PHOSPHORTAG";
            }
        }
    if (shadowName == null)
        shadowName = "phosphorShadowLVFor" + shadows + "XX" + createdLVIdx;
    LocalVariableNode newLVN = new LocalVariableNode(shadowName, type.getDescriptor(), null, new LabelNode(lbl), new LabelNode(end), idx);
    createdLVs.add(newLVN);
    curLocalIdxToLVNode.put(idx, newLVN);
    createdLVIdx++;
    shadowLVMap.put(idx, origLVMap.get(shadows));
    varToShadowVar.put(shadows, idx);
    return idx;
}
Also used : LabelNode(org.objectweb.asm.tree.LabelNode) Label(org.objectweb.asm.Label) LocalVariableNode(org.objectweb.asm.tree.LocalVariableNode)

Example 15 with LocalVariableNode

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

the class LocalVariableManager method newLocal.

@Deprecated
public int newLocal(Type type) {
    int idx = super.newLocal(type);
    Label lbl = new Label();
    super.visitLabel(lbl);
    LocalVariableNode newLVN = new LocalVariableNode("phosphorShadowLV" + createdLVIdx, type.getDescriptor(), null, new LabelNode(lbl), new LabelNode(end), idx);
    createdLVs.add(newLVN);
    curLocalIdxToLVNode.put(idx, newLVN);
    createdLVIdx++;
    return idx;
}
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