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");
}
}
}
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();
}
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();
}
}
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;
}
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;
}
Aggregations