![JAR search and dependency download from the Maven repository](/logo.png)
edu.columbia.cs.psl.phosphor.instrumenter.LocalVariableManager Maven / Gradle / Ivy
The newest version!
package edu.columbia.cs.psl.phosphor.instrumenter;
import edu.columbia.cs.psl.phosphor.Configuration;
import edu.columbia.cs.psl.phosphor.TaintUtils;
import edu.columbia.cs.psl.phosphor.instrumenter.analyzer.NeverNullArgAnalyzerAdapter;
import edu.columbia.cs.psl.phosphor.instrumenter.analyzer.TaggedValue;
import edu.columbia.cs.psl.phosphor.org.objectweb.asm.commons.OurLocalVariablesSorter;
import edu.columbia.cs.psl.phosphor.runtime.TaintSentinel;
import edu.columbia.cs.psl.phosphor.struct.ControlTaintTagStack;
import edu.columbia.cs.psl.phosphor.struct.EnqueuedTaint;
import edu.columbia.cs.psl.phosphor.struct.ExceptionalTaintData;
import org.objectweb.asm.Label;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;
import org.objectweb.asm.tree.LabelNode;
import org.objectweb.asm.tree.LocalVariableNode;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map.Entry;
public class LocalVariableManager extends OurLocalVariablesSorter implements Opcodes {
private NeverNullArgAnalyzerAdapter analyzer;
private static final boolean DEBUG = false;
int createdLVIdx = 0;
HashSet createdLVs = new HashSet();
HashMap curLocalIdxToLVNode = new HashMap();
MethodVisitor uninstMV;
Type returnType;
int lastArg;
ArrayList oldArgTypes = new ArrayList();
boolean isIgnoreEverything = false;
@Override
public void visitInsn(int opcode) {
if(opcode == TaintUtils.IGNORE_EVERYTHING)
isIgnoreEverything = !isIgnoreEverything;
super.visitInsn(opcode);
}
private boolean isInMethodThatsTooBig;
@Override
public void visitIincInsn(int var, int increment) {
if(isIgnoreEverything){
isInMethodThatsTooBig = true;
mv.visitIincInsn(var, increment);
}
else
super.visitIincInsn(var, increment);
}
@Override
public void visitVarInsn(int opcode, int var) {
if(opcode == TaintUtils.BRANCH_END || opcode == TaintUtils.BRANCH_START || isIgnoreEverything)
{
mv.visitVarInsn(opcode, var);
return;
}
if (opcode == TaintUtils.IGNORE_EVERYTHING)
isInMethodThatsTooBig = true;
else
super.visitVarInsn(opcode, var);
}
public HashMap varToShadowVar = new HashMap();
private boolean generateExtraDebug;
private Type[] args;
private boolean isStatic;
private int extraLVsInArg;
public LocalVariableManager(int access, String desc, MethodVisitor mv, NeverNullArgAnalyzerAdapter analyzer, MethodVisitor uninstMV, boolean generateExtraDebug) {
super(Configuration.ASM_VERSION, access, desc, mv);
this.analyzer = analyzer;
this.uninstMV = uninstMV;
returnType = Type.getReturnType(desc);
args = Type.getArgumentTypes(desc);
if((access & Opcodes.ACC_STATIC) == 0){
lastArg++;
oldArgTypes.add(Type.getType("Lthis;"));
}
else
isStatic = true;
for (int i = 0; i < args.length; i++) {
lastArg += args[i].getSize();
oldArgTypes.add(args[i]);
if(args[i].getSize() > 1)
{
oldArgTypes.add(Type.getType("Ltop;"));
}
if(args[i].getDescriptor().equals(Type.getDescriptor(ControlTaintTagStack.class)))
{
extraLVsInArg++;
idxOfMasterControlLV = lastArg-1;
}
if(args[i].getDescriptor().equals(Configuration.TAINT_TAG_DESC))
extraLVsInArg++;
if(args[i].getDescriptor().equals(Type.getType(TaintSentinel.class)))
extraLVsInArg++;
}
lastArg--;
if(returnType.getDescriptor().startsWith("Ledu/columbia/cs/psl/phosphor/struct/Tainted"))
preAllocedReturnTypes.put(returnType, lastArg);
end = new Label();
// System.out.println("New LVS");
// System.out.println("LVS thinks its at " + lastArg);
this.generateExtraDebug = generateExtraDebug;
}
public void freeTmpLV(int idx) {
for (TmpLV v : tmpLVs) {
if (v.idx == idx && v.inUse) {
Label lbl = new Label();
super.visitLabel(lbl);
curLocalIdxToLVNode.get(v.idx).end = new LabelNode(lbl);
v.inUse = false;
v.owner = null;
if(idx < analyzer.locals.size())
analyzer.locals.set(idx, Opcodes.TOP);
return;
}
}
// System.err.println(tmpLVs);
throw new IllegalArgumentException("asked to free tmp lv " + idx + " but couldn't find it?");
}
@Deprecated
public int newLocal(Type type) {
throw new UnsupportedOperationException();
}
HashMap origLVMap = new HashMap();
HashMap shadowLVMap = new HashMap();
HashMap shadowLVMapType = new HashMap();
// HashSet 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;
}
int jumpIdx;
int idxOfMasterControlLV = -1;
int idxOfMasterExceptionLV = -1;
public int getIdxOfMasterExceptionLV() {
return idxOfMasterExceptionLV;
}
public int createExceptionTaintLV()
{
int idx = super.newLocal(Type.getType(ExceptionalTaintData.class));
if (ctrlTagStartLbl == null) {
ctrlTagStartLbl = new Label();
super.visitLabel(ctrlTagStartLbl);
}
LocalVariableNode newLVN = new LocalVariableNode("phosphorExceptionTaintData", Type.getDescriptor(ExceptionalTaintData.class), null, new LabelNode(ctrlTagStartLbl), new LabelNode(end), idx);
createdLVs.add(newLVN);
analyzer.locals.add(idx, Type.getInternalName(ExceptionalTaintData.class));
this.idxOfMasterExceptionLV = idx;
return idx;
}
public int getIdxOfMasterControlLV() {
return idxOfMasterControlLV;
}
private Label ctrlTagStartLbl;
public int createMasterControlTaintLV()
{
int idx = super.newLocal(Type.getType(ControlTaintTagStack.class));
if (ctrlTagStartLbl == null) {
ctrlTagStartLbl = new Label();
super.visitLabel(ctrlTagStartLbl);
}
LocalVariableNode newLVN = new LocalVariableNode("phosphorJumpControlTag" + jumpIdx, Type.getDescriptor(ControlTaintTagStack.class), null, new LabelNode(ctrlTagStartLbl), new LabelNode(end), idx);
createdLVs.add(newLVN);
analyzer.locals.add(idx, Type.getInternalName(ControlTaintTagStack.class));
this.idxOfMasterControlLV = idx;
jumpIdx++;
return idx;
}
public int newControlTaintLV()
{
int idx = super.newLocal(Type.getType("[I"));
if (ctrlTagStartLbl == null) {
ctrlTagStartLbl = new Label();
super.visitLabel(ctrlTagStartLbl);
}
LocalVariableNode newLVN = new LocalVariableNode("phosphorJumpControlTag", "[I", null, new LabelNode(ctrlTagStartLbl), new LabelNode(end), idx);
createdLVs.add(newLVN);
// System.out.println("Create taint tag at " + idx);
analyzer.locals.add(idx, "[I");
jumpIdx++;
return idx;
}
public int newControlExceptionTaintLV()
{
Type t = Type.getType(EnqueuedTaint.class);
int idx = super.newLocal(t);
if (ctrlTagStartLbl == null) {
ctrlTagStartLbl = new Label();
super.visitLabel(ctrlTagStartLbl);
}
LocalVariableNode newLVN = new LocalVariableNode("phosphorExceptionData", t.getDescriptor(), null, new LabelNode(ctrlTagStartLbl), new LabelNode(end), idx);
createdLVs.add(newLVN);
// System.out.println("Create taint tag at " + idx);
analyzer.locals.add(idx, t.getInternalName());
// jumpIdx++;
return idx;
}
protected int remap(int var, Type type) {
int ret = super.remap(var, type);
// System.out.println(var +" -> " + ret);
origLVMap.put(ret, var);
Object objType = "[I";
switch(type.getSort()){
case Type.BOOLEAN:
case Type.SHORT:
case Type.INT:
objType = Opcodes.INTEGER;
break;
case Type.LONG:
objType= Opcodes.LONG;
break;
case Type.DOUBLE:
objType= Opcodes.DOUBLE;
break;
case Type.FLOAT:
objType= Opcodes.FLOAT;
break;
}
shadowLVMapType.put(ret, objType);
return ret;
}
private int newPreAllocedReturnType(Type type) {
int idx = super.newLocal(type);
Label lbl = new Label();
super.visitLabel(lbl);
// System.out.println("End is going to be " + end);
LocalVariableNode newLVN = new LocalVariableNode("phosphorReturnPreAlloc" + createdLVIdx, type.getDescriptor(), null, new LabelNode(lbl), new LabelNode(end), idx);
createdLVs.add(newLVN);
curLocalIdxToLVNode.put(idx, newLVN);
createdLVIdx++;
analyzer.locals.add(idx, type.getInternalName());
return idx;
}
/**
* Gets a tmp lv capable of storing the top stack el
*
* @return
*/
public int getTmpLV() {
Object obj = analyzer.stack.get(analyzer.stack.size() - 1);
// System.out.println("gettmplv " + obj);
if (obj instanceof String)
return getTmpLV(Type.getObjectType((String) obj));
if (obj == Opcodes.INTEGER)
return getTmpLV(Type.INT_TYPE);
if (obj == Opcodes.FLOAT)
return getTmpLV(Type.FLOAT_TYPE);
if (obj == Opcodes.DOUBLE)
return getTmpLV(Type.DOUBLE_TYPE);
if (obj == Opcodes.LONG)
return getTmpLV(Type.LONG_TYPE);
if (obj == Opcodes.TOP) {
obj = analyzer.stack.get(analyzer.stack.size() - 2);
if (obj == Opcodes.DOUBLE)
return getTmpLV(Type.DOUBLE_TYPE);
if (obj == Opcodes.LONG)
return getTmpLV(Type.LONG_TYPE);
}
return getTmpLV(Type.getType("Ljava/lang/Object;"));
}
HashSet tmpLVIdices = new HashSet();
public int getTmpLV(Type t) {
if (t.getDescriptor().equals("java/lang/Object;"))
throw new IllegalArgumentException();
for (TmpLV lv : tmpLVs) {
if (!lv.inUse && lv.type.getSize() == t.getSize()) {
if (!lv.type.equals(t)) {
//End the old LV node, make a new one
Label lbl = new Label();
super.visitLabel(lbl);
LocalVariableNode newLVN = new LocalVariableNode("phosphorTempStack" + createdLVIdx, t.getDescriptor(), null, new LabelNode(lbl), new LabelNode(end), lv.idx);
createdLVs.add(newLVN);
curLocalIdxToLVNode.put(lv.idx, newLVN);
createdLVIdx++;
remapLocal(lv.idx, t);
if (analyzer.locals != null && lv.idx < analyzer.locals.size()) {
analyzer.locals.set(lv.idx, TaintUtils.getStackTypeForType(t));
}
lv.type = t;
}
lv.inUse = true;
if (DEBUG) {
lv.owner = new IllegalStateException("Unclosed tmp lv created at:");
lv.owner.fillInStackTrace();
}
return lv.idx;
}
}
int idx = super.newLocal(t);
Label lbl = new Label();
super.visitLabel(lbl);
LocalVariableNode newLVN = new LocalVariableNode("phosphorTempStack" + createdLVIdx, t.getDescriptor(), null, new LabelNode(lbl), new LabelNode(end), idx);
createdLVs.add(newLVN);
curLocalIdxToLVNode.put(idx, newLVN);
createdLVIdx++;
TmpLV newLV = new TmpLV();
newLV.idx = idx;
newLV.type = t;
newLV.inUse = true;
tmpLVs.add(newLV);
tmpLVIdices.add(newLV.idx);
if (DEBUG) {
newLV.owner = new IllegalStateException("Unclosed tmp lv created at:");
newLV.owner.fillInStackTrace();
}
return newLV.idx;
}
ArrayList tmpLVs = new ArrayList();
boolean endVisited = false;
@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;
}
if(!Configuration.SKIP_LOCAL_VARIABLE_TABLE)
for (LocalVariableNode n : createdLVs) {
uninstMV.visitLocalVariable(n.name, n.desc, n.signature, n.start.getLabel(), n.end.getLabel(), n.index);
}
createdLVs.clear();
}
}
Label end;
@Override
public void visitMaxs(int maxStack, int maxLocals) {
if(!endVisited)
{
super.visitLabel(end);
endVisited = true;
}
if(generateExtraDebug && !Configuration.SKIP_LOCAL_VARIABLE_TABLE)
{
int n = 0;
if(!isStatic)
{
super.visitLocalVariable("argidx"+n, "Ljava/lang/Object;", null, this.start, this.end, n);
n++;
}
for(Type t : args)
{
super.visitLocalVariable("argidx"+n, t.getDescriptor(), null, this.start, this.end, n);
n+=t.getSize();
}
}
super.visitMaxs(maxStack, maxLocals);
}
@Override
public void visitEnd() {
super.visitEnd();
for (TmpLV l : tmpLVs) {
if (l.inUse)
throw l.owner;
}
}
private class TmpLV {
int idx;
Type type;
boolean inUse;
IllegalStateException owner;
@Override
public String toString() {
return "TmpLV [idx=" + idx + ", type=" + type + ", inUse=" + inUse + "]";
}
}
Label start = new Label();;
public void visitCode() {
super.visitCode();
super.visitLabel(start);
if (primitiveArrayFixer != null)
for (Type t : primitiveArrayFixer.wrapperTypesToPreAlloc) {
if (t.equals(returnType)) {
preAllocedReturnTypes.put(t, lastArg);
} else {
int lv = newPreAllocedReturnType(t);
preAllocedReturnTypes.put(t, lv);
super.visitTypeInsn(NEW, t.getInternalName());
super.visitInsn(DUP);
super.visitMethodInsn(INVOKESPECIAL, t.getInternalName(), "", "()V", false);
mv.visitVarInsn(ASTORE, lv);
// System.out.println("Created LV Storage at " + lv);
}
}
}
HashMap preAllocedReturnTypes = new HashMap();
PrimitiveArrayAnalyzer primitiveArrayFixer;
public HashMap varsToRemove = new HashMap();
public void setPrimitiveArrayAnalyzer(PrimitiveArrayAnalyzer primitiveArrayFixer) {
this.primitiveArrayFixer = primitiveArrayFixer;
}
public int getPreAllocedReturnTypeVar(Type newReturnType) {
// System.out.println(preAllocedReturnTypes);
if(!preAllocedReturnTypes.containsKey(newReturnType))
throw new IllegalArgumentException("Got " + newReturnType + " but have " + preAllocedReturnTypes);
return preAllocedReturnTypes.get(newReturnType);
}
@Override
public void visitLineNumber(int line, Label start) {
// System.out.println("LVM Line " + line);
super.visitLineNumber(line, start);
}
@Override
public void visitFrame(final int type, final int nLocal,
final Object[] local, final int nStack, final Object[] stack) {
// System.out.println("VF");
if(type == TaintUtils.RAW_INSN)
{
// System.out.println("ZZ");
// System.out.println("Raw frame from " + Arrays.toString(local));
mv.visitFrame(Opcodes.F_NEW, nLocal, local, nStack, stack);
return;
}
if (type != Opcodes.F_NEW) { // uncompressed frame
throw new IllegalStateException(
"ClassReader.accept() should be called with EXPAND_FRAMES flag");
}
if (isInMethodThatsTooBig || (!changed && !isFirstFrame)) { // optimization for the case where mapping = identity
mv.visitFrame(type, nLocal, local, nStack, stack);
return;
}
isFirstFrame = false;
// System.out.println("nlocal " + nLocal);
// System.out.println(Arrays.toString(local));
// System.out.println(Arrays.toString(newLocals));
// creates a copy of newLocals
Object[] oldLocals = new Object[newLocals.length];
System.arraycopy(newLocals, 0, oldLocals, 0, oldLocals.length);
updateNewLocals(newLocals);
for(int i = 0; i < newLocals.length; i++)
{
//Ignore tmp lv's in the stack frames.
if(tmpLVIdices.contains(i))
newLocals[i] = Opcodes.TOP;
}
ArrayList
© 2015 - 2025 Weber Informatics LLC | Privacy Policy