Search in sources :

Example 1 with BoundedSet

use of com.jopdesign.dfa.framework.BoundedSetFactory.BoundedSet in project jop by jop-devel.

the class SymbolicPointsTo method transfer.

public ContextMap<CallString, SymbolicAddressMap> transfer(InstructionHandle stmt, FlowEdge edge, ContextMap<CallString, SymbolicAddressMap> input, Interpreter<CallString, SymbolicAddressMap> interpreter, Map<InstructionHandle, ContextMap<CallString, SymbolicAddressMap>> state) {
    Context context = new Context(input.getContext());
    if (DEBUG_PRINT) {
        System.out.println("[S] " + context.callString.toStringList() + ": " + context.method() + " / " + stmt);
    }
    SymbolicAddressMap in = input.get(context.callString);
    ContextMap<CallString, SymbolicAddressMap> retval = new ContextMap<CallString, SymbolicAddressMap>(context, input);
    Instruction instruction = stmt.getInstruction();
    int newStackPtr = context.stackPtr + instruction.produceStack(context.constPool()) - instruction.consumeStack(context.constPool());
    int opcode = instruction.getOpcode();
    switch(opcode) {
        /* Constants (boring) */
        case Constants.DCONST_0:
        case Constants.DCONST_1:
        case Constants.LCONST_0:
        case Constants.LCONST_1:
        /* Instructions above need two stack slots */
        case Constants.FCONST_0:
        case Constants.FCONST_1:
        case Constants.FCONST_2:
        case Constants.ICONST_M1:
        case Constants.ICONST_0:
        case Constants.ICONST_1:
        case Constants.ICONST_2:
        case Constants.ICONST_3:
        case Constants.ICONST_4:
        case Constants.ICONST_5:
        case Constants.BIPUSH:
        case Constants.SIPUSH:
            {
                retval.put(context.callString, in.cloneFilterStack(newStackPtr));
            }
            break;
        case Constants.ACONST_NULL:
            {
                // Null -> No reference
                SymbolicAddressMap result = in.cloneFilterStack(newStackPtr);
                result.putStack(newStackPtr - 1, bsFactory.empty());
                retval.put(context.callString, result);
            }
            break;
        /* Long/Double Constants */
        case Constants.LDC2_W:
            {
                retval.put(context.callString, in.cloneFilterStack(newStackPtr));
            }
            break;
        /* Int/Float/String Constants */
        case Constants.LDC:
        case Constants.LDC_W:
            {
                LDC ldc = (LDC) instruction;
                Type t = ldc.getType(context.constPool());
                if (t instanceof ReferenceType) {
                    SymbolicAddressMap result = in.cloneFilterStack(newStackPtr);
                    /* FIXME: This is overly conservative, but class pointer not available here */
                    String classContext = context.getMethodInfo().getMemberID().toString();
                    SymbolicAddress addr = SymbolicAddress.stringLiteral(classContext, ldc.getIndex());
                    result.putStack(newStackPtr - 1, bsFactory.singleton(addr));
                    retval.put(context.callString, result);
                } else {
                    retval.put(context.callString, in.cloneFilterStack(newStackPtr));
                }
            }
            break;
        case Constants.DSTORE:
        case Constants.DSTORE_0:
        case Constants.DSTORE_1:
        case Constants.DSTORE_2:
        case Constants.DSTORE_3:
        case Constants.LSTORE:
        case Constants.LSTORE_0:
        case Constants.LSTORE_1:
        case Constants.LSTORE_2:
        case Constants.LSTORE_3:
        case Constants.FSTORE:
        case Constants.FSTORE_0:
        case Constants.FSTORE_1:
        case Constants.FSTORE_2:
        case Constants.FSTORE_3:
        case Constants.ISTORE_0:
        case Constants.ISTORE_1:
        case Constants.ISTORE_2:
        case Constants.ISTORE_3:
        case Constants.ISTORE:
            {
                retval.put(context.callString, in.cloneFilterStack(newStackPtr));
            }
            break;
        // 
        case Constants.ASTORE_0:
        case Constants.ASTORE_1:
        case Constants.ASTORE_2:
        case Constants.ASTORE_3:
        case Constants.ASTORE:
            {
                // copy value to local variable
                StoreInstruction instr = (StoreInstruction) instruction;
                SymbolicAddressMap result = in.cloneFilterStack(newStackPtr);
                if (DEBUG_PRINT) {
                    System.out.println(String.format("[DD] Copy: stack[%d] <- stack[%d]", instr.getIndex(), context.stackPtr - 1));
                }
                result.copyStack(in, instr.getIndex(), context.stackPtr - 1);
                retval.put(context.callString, result);
            }
            break;
        /* Load variables (boring) */
        case Constants.DLOAD_0:
        case Constants.DLOAD_1:
        case Constants.DLOAD_2:
        case Constants.DLOAD_3:
        case Constants.DLOAD:
        case Constants.LLOAD_0:
        case Constants.LLOAD_1:
        case Constants.LLOAD_2:
        case Constants.LLOAD_3:
        case Constants.LLOAD:
        /* Instructions above need two stack slots */
        case Constants.FLOAD_0:
        case Constants.FLOAD_1:
        case Constants.FLOAD_2:
        case Constants.FLOAD_3:
        case Constants.FLOAD:
        case Constants.ILOAD_0:
        case Constants.ILOAD_1:
        case Constants.ILOAD_2:
        case Constants.ILOAD_3:
        case Constants.ILOAD:
            {
                retval.put(context.callString, in.cloneFilterStack(newStackPtr));
            }
            break;
        /* Floating Point Comparison (boring) */
        case Constants.DCMPG:
        case Constants.DCMPL:
        case Constants.LCMP:
        /* Instructions above need two stack slots */
        case Constants.FCMPG:
        case Constants.FCMPL:
            {
                retval.put(context.callString, in.cloneFilterStack(newStackPtr));
            }
            break;
        case Constants.ALOAD_0:
        case Constants.ALOAD_1:
        case Constants.ALOAD_2:
        case Constants.ALOAD_3:
        case Constants.ALOAD:
            {
                LoadInstruction instr = (LoadInstruction) instruction;
                // copy value from local variable
                SymbolicAddressMap result = in.cloneFilterStack(newStackPtr);
                result.copyStack(in, context.stackPtr, instr.getIndex());
                retval.put(context.callString, result);
            }
            break;
        // Access Object Handle (area), top of stack
        case Constants.ARRAYLENGTH:
            {
                putResult(stmt, context, input.get(context.callString).getStack(context.stackPtr - 1));
                retval.put(context.callString, in.cloneFilterStack(newStackPtr));
            }
            break;
        // Access Object Handle, second on stack
        case Constants.PUTFIELD:
            {
                PUTFIELD instr = (PUTFIELD) instruction;
                putResult(stmt, context, input.get(context.callString).getStack(context.stackPtr - 1 - instr.getType(context.constPool()).getSize()));
                SymbolicAddressMap result = in.cloneFilterStack(newStackPtr);
                // Change alias information
                if (instr.getFieldType(context.constPool()) instanceof ReferenceType) {
                    String ty = instr.getFieldType(context.constPool()).getSignature();
                    result.addAlias(ty, in.getStack(context.stackPtr - 1));
                }
                retval.put(context.callString, result);
            }
            break;
        // Access Object Handle, top of stack
        case Constants.GETFIELD:
            {
                putResult(stmt, context, input.get(context.callString).getStack(context.stackPtr - 1));
                GETFIELD instr = (GETFIELD) instruction;
                SymbolicAddressMap result = in.cloneFilterStack(newStackPtr);
                if (instr.getFieldType(context.constPool()) instanceof ReferenceType) {
                    BoundedSet<SymbolicAddress> newMapping = SymbolicAddress.fieldAccess(bsFactory, in.getStack(context.stackPtr - 1), instr.getFieldName(context.constPool()));
                    newMapping.addAll(in.getAliases(instr.getFieldType(context.constPool()).getSignature()));
                    result.putStack(context.stackPtr - 1, newMapping);
                }
                retval.put(context.callString, result);
            }
            break;
        // Handles the same way as MOV
        case Constants.PUTSTATIC:
            {
                PUTSTATIC instr = (PUTSTATIC) instruction;
                SymbolicAddressMap result = in.cloneFilterStack(newStackPtr);
                if (instr.getFieldType(context.constPool()) instanceof ReferenceType) {
                    BoundedSet<SymbolicAddress> pointers = in.getStack(context.stackPtr - 1);
                    result.putHeap(fieldSignature(context, instr), pointers);
                }
                retval.put(context.callString, result);
            }
            break;
        // Handled the same as MOV
        case Constants.GETSTATIC:
            {
                GETSTATIC instr = (GETSTATIC) instruction;
                SymbolicAddressMap result = in.cloneFilterStack(newStackPtr);
                if (instr.getFieldType(context.constPool()) instanceof ReferenceType) {
                    result.putStack(context.stackPtr, in.getHeap(fieldSignature(context, instr)));
                }
                retval.put(context.callString, result);
            }
            break;
        case Constants.LASTORE:
        case Constants.DASTORE:
        case Constants.IASTORE:
        case Constants.FASTORE:
        case Constants.CASTORE:
        case Constants.SASTORE:
        case Constants.BASTORE:
            {
                int offset = 3;
                if (opcode == Constants.LASTORE || opcode == Constants.DASTORE)
                    offset = 4;
                putResult(stmt, context, input.get(context.callString).getStack(context.stackPtr - offset));
                retval.put(context.callString, in.cloneFilterStack(newStackPtr));
            }
            break;
        // changing the heap -> TOP
        case Constants.AASTORE:
            {
                putResult(stmt, context, input.get(context.callString).getStack(context.stackPtr - 3));
                AASTORE instr = (AASTORE) stmt.getInstruction();
                SymbolicAddressMap result = in.cloneFilterStack(newStackPtr);
                // Change alias information
                if (instr.getType(context.constPool()) instanceof ReferenceType) {
                    String ty = instr.getType(context.constPool()).getSignature();
                    result.addAlias(ty, in.getStack(context.stackPtr - 1));
                }
                retval.put(context.callString, result);
            }
            break;
        case Constants.DALOAD:
        case Constants.LALOAD:
        case Constants.IALOAD:
        case Constants.FALOAD:
        case Constants.CALOAD:
        case Constants.SALOAD:
        case Constants.BALOAD:
            {
                putResult(stmt, context, input.get(context.callString).getStack(context.stackPtr - 2));
                retval.put(context.callString, in.cloneFilterStack(newStackPtr));
            }
            break;
        // TODO: Use index info
        case Constants.AALOAD:
            {
                putResult(stmt, context, input.get(context.callString).getStack(context.stackPtr - 2));
                // AALOAD instr = (AALOAD)instruction;
                SymbolicAddressMap result = in.cloneFilterStack(newStackPtr);
                BoundedSet<SymbolicAddress> objectMapping = in.getStack(context.stackPtr - 2);
                BoundedSet<SymbolicAddress> newMapping;
                LoopBounds bounds = interpreter.getDFATool().getLoopBounds();
                if (executedOnce.query(stmt)) {
                    newMapping = bsFactory.singleton(SymbolicAddress.newName());
                } else if (objectMapping.isSaturated() || bounds == null) {
                    newMapping = bsFactory.top();
                } else {
                    Interval interval = bounds.getArrayIndices(stmt, context.callString);
                    if (interval.hasLb() && interval.hasUb()) {
                        newMapping = bsFactory.empty();
                        for (SymbolicAddress addr : objectMapping.getSet()) {
                            for (int i = interval.getLb(); i <= interval.getUb(); i++) {
                                newMapping.add(addr.accessArray(i));
                            }
                        }
                    } else {
                        newMapping = bsFactory.top();
                    }
                }
                // Doesn't work, but is probably stupid anyway :(
                // LoopBounds bounds = interpreter.getDFATool().getLoopBounds();
                // bounds.getArraySizes().get(stmt).get(context.callString);
                // newMapping = bsFactory.empty();
                // Interval[] sizeBounds = { new Interval(2,3) };
                // for(Interval i : sizeBounds) {
                // if(! i.hasUb()) {
                // newMapping = bsFactory.top();
                // }
                // int ub = i.getUb();
                // for(int j = 0; j <= ub; j++) {
                // for(SymbolicAddress addr: objectMapping.getSet()) {
                // newMapping.add(addr.accessArray(j));
                // }
                // }
                // }
                // }
                result.putStack(context.stackPtr - 2, newMapping);
                retval.put(context.callString, result);
            }
            break;
        case Constants.DUP:
            {
                // copy value on stack
                SymbolicAddressMap result = in.cloneFilterStack(newStackPtr);
                result.copyStack(in, context.stackPtr, context.stackPtr - 1);
                retval.put(context.callString, result);
            }
            break;
        case Constants.DUP_X1:
            {
                // copy value on stack
                SymbolicAddressMap result = in.cloneFilterStack(context.stackPtr - 2);
                result.copyStack(in, context.stackPtr - 2, context.stackPtr - 1);
                result.copyStack(in, context.stackPtr - 1, context.stackPtr - 2);
                result.copyStack(in, context.stackPtr, context.stackPtr - 1);
                retval.put(context.callString, result);
            }
            break;
        case Constants.DUP_X2:
            {
                // copy value on stack
                SymbolicAddressMap result = in.cloneFilterStack(context.stackPtr - 3);
                result.copyStack(in, context.stackPtr - 3, context.stackPtr - 1);
                result.copyStack(in, context.stackPtr - 2, context.stackPtr - 3);
                result.copyStack(in, context.stackPtr - 1, context.stackPtr - 2);
                result.copyStack(in, context.stackPtr, context.stackPtr - 1);
                retval.put(context.callString, result);
            }
            break;
        case Constants.DUP2:
            {
                // v1,v2 -> v1,v2,v1,v2
                SymbolicAddressMap result = in.cloneFilterStack(context.stackPtr);
                result.copyStack(in, context.stackPtr, context.stackPtr - 2);
                result.copyStack(in, context.stackPtr + 1, context.stackPtr - 1);
                retval.put(context.callString, result);
            }
            break;
        case Constants.POP:
        case Constants.POP2:
            {
                retval.put(context.callString, in.cloneFilterStack(newStackPtr));
            }
            break;
        case Constants.IINC:
            {
                retval.put(context.callString, in.cloneFilterStack(newStackPtr));
            }
            break;
        case Constants.IADD:
        case Constants.ISUB:
        case Constants.INEG:
        case Constants.IUSHR:
        case Constants.ISHR:
        case Constants.IAND:
        case Constants.IOR:
        case Constants.IXOR:
        case Constants.IMUL:
        case Constants.IDIV:
        case Constants.IREM:
        case Constants.ISHL:
            {
                retval.put(context.callString, in.cloneFilterStack(newStackPtr));
            }
            break;
        /* Long,Float and Double operations (boring) */
        case Constants.DADD:
        case Constants.DSUB:
        case Constants.DMUL:
        case Constants.DDIV:
        case Constants.DREM:
        case Constants.LADD:
        case Constants.LSUB:
        case Constants.LUSHR:
        case Constants.LSHR:
        case Constants.LAND:
        case Constants.LOR:
        case Constants.LXOR:
        case Constants.LMUL:
        case Constants.LDIV:
        case Constants.LREM:
        case Constants.LSHL:
        /* Instructions above need two stack slots */
        case Constants.DNEG:
        case Constants.LNEG:
        case Constants.FADD:
        case Constants.FSUB:
        case Constants.FNEG:
        case Constants.FMUL:
        case Constants.FDIV:
        case Constants.FREM:
            {
                retval.put(context.callString, in.cloneFilterStack(newStackPtr));
            }
            break;
        /* Conversion of primitives (boring) */
        case Constants.D2F:
        case Constants.D2I:
        /* Instructions above need two stack slots */
        case Constants.D2L:
            {
                retval.put(context.callString, in.cloneFilterStack(newStackPtr));
            }
            break;
        case Constants.L2F:
        case Constants.L2I:
        /* Instructions above need two stack slots */
        case Constants.L2D:
            {
                retval.put(context.callString, in.cloneFilterStack(newStackPtr));
            }
            break;
        case Constants.F2D:
        case Constants.I2D:
        case Constants.F2L:
        case Constants.I2L:
        /* Instructions above need one stack slot less */
        case Constants.F2I:
        case Constants.I2B:
        case Constants.I2C:
        case Constants.I2F:
        case Constants.I2S:
            {
                retval.put(context.callString, in.cloneFilterStack(newStackPtr));
            }
            break;
        case Constants.MONITORENTER:
            // not supported yet
            if (ASSUME_NO_CONC)
                retval.put(context.callString, in.cloneFilterStack(newStackPtr));
            else
                retval.put(context.callString, SymbolicAddressMap.top());
            break;
        case Constants.MONITOREXIT:
            // not supported yet
            retval.put(context.callString, in.cloneFilterStack(newStackPtr));
            break;
        case Constants.CHECKCAST:
            retval.put(context.callString, in.cloneFilterStack(newStackPtr));
            break;
        case Constants.INSTANCEOF:
            {
                retval.put(context.callString, in.cloneFilterStack(newStackPtr));
            }
            break;
        case Constants.NEW:
        case Constants.NEWARRAY:
        case Constants.ANEWARRAY:
            {
                SymbolicAddressMap result = in.cloneFilterStack(newStackPtr);
                BoundedSet<SymbolicAddress> newMapping;
                if (executedOnce.query(stmt)) {
                    newMapping = bsFactory.singleton(SymbolicAddress.newName());
                } else {
                    newMapping = bsFactory.top();
                }
                int objPtr = (instruction.getOpcode() == Constants.NEW) ? context.stackPtr : (context.stackPtr - 1);
                result.putStack(objPtr, newMapping);
                retval.put(context.callString, result);
            }
            break;
        case Constants.MULTIANEWARRAY:
            {
                // not supported yet
                retval.put(context.callString, SymbolicAddressMap.top());
            }
            break;
        case Constants.GOTO:
            retval.put(context.callString, in.cloneFilterStack(newStackPtr));
            break;
        case Constants.IFNULL:
        case Constants.IFNONNULL:
            {
                retval.put(context.callString, in.cloneFilterStack(newStackPtr));
            }
            break;
        case Constants.IF_ACMPEQ:
        case Constants.IF_ACMPNE:
            {
                retval.put(context.callString, in.cloneFilterStack(newStackPtr));
            }
            break;
        case Constants.IFEQ:
        case Constants.IFNE:
        case Constants.IFLT:
        case Constants.IFGE:
        case Constants.IFLE:
        case Constants.IFGT:
            retval.put(context.callString, in.cloneFilterStack(newStackPtr));
            break;
        case Constants.IF_ICMPEQ:
        case Constants.IF_ICMPNE:
        case Constants.IF_ICMPLT:
        case Constants.IF_ICMPGE:
        case Constants.IF_ICMPGT:
        case Constants.IF_ICMPLE:
            retval.put(context.callString, in.cloneFilterStack(newStackPtr));
            break;
        case Constants.LOOKUPSWITCH:
        case Constants.TABLESWITCH:
            retval.put(context.callString, in.cloneFilterStack(newStackPtr));
            break;
        case Constants.INVOKEVIRTUAL:
        case Constants.INVOKEINTERFACE:
        case Constants.INVOKESTATIC:
        case Constants.INVOKESPECIAL:
            {
                DFATool p = interpreter.getDFATool();
                Set<String> receivers = p.getReceivers(stmt, context.callString);
                retval.put(context.callString, new SymbolicAddressMap(bsFactory));
                if (receivers == null || receivers.size() == 0) {
                    String errMsg = String.format("%s : invoke %s: %s receivers", context.method(), instruction.toString(context.constPool().getConstantPool()), (receivers == null ? "Unknown" : "No"));
                    // Get static receivers (FIXME: this just workarounds DFA bugs)
                    if (opcode == Constants.INVOKESTATIC) {
                        receivers = new HashSet<String>();
                        InvokeInstruction invInstruction = (InvokeInstruction) instruction;
                        String klass = invInstruction.getClassName(context.constPool());
                        String name = invInstruction.getMethodName(context.constPool());
                        String sig = invInstruction.getSignature(context.constPool());
                        String recv = klass + "." + name + sig;
                        Logger.getLogger(this.getClass()).info("Using static receiver: " + recv);
                        receivers.add(recv);
                    } else {
                        Logger.getLogger(this.getClass()).error(errMsg);
                        throw new AssertionError(errMsg);
                    }
                }
                if (instruction.getOpcode() == Constants.INVOKEVIRTUAL || instruction.getOpcode() == Constants.INVOKEINTERFACE) {
                    MethodInfo mi = p.getMethod(receivers.iterator().next());
                    int refPos = MethodHelper.getArgSize(mi);
                    // mi.methodId,refPos,context.stackPtr,input.get(context.callString)));
                    try {
                        putResult(stmt, context, input.get(context.callString).getStack(context.stackPtr - refPos));
                    } catch (Error e) {
                        System.err.println("We have problems with method " + mi);
                        System.err.println(e.getMessage());
                    }
                }
                for (String methodName : receivers) {
                    doInvoke(methodName, stmt, context, input, interpreter, state, retval);
                }
            }
            break;
        case Constants.ARETURN:
            {
                SymbolicAddressMap result = in.cloneFilterStack(0);
                // store results
                result.copyStack(in, 0, context.stackPtr - 1);
                retval.put(context.callString, result);
            }
            break;
        /* The values of other return statements are not of interest here */
        case Constants.DRETURN:
        case Constants.LRETURN:
        case Constants.FRETURN:
        case Constants.IRETURN:
        case Constants.RETURN:
            {
                retval.put(context.callString, in.cloneFilterStack(newStackPtr));
            }
            break;
        default:
            System.err.println("unknown instruction: " + stmt + " in method " + context.method());
            retval.put(context.callString, in.cloneFilterStack(newStackPtr));
            break;
    }
    // DEBUGGING
    if (DEBUG_PRINT) {
        System.out.println("[F] " + context.method() + " / " + stmt);
        System.out.println("  Stackptr: " + context.stackPtr + " -> " + newStackPtr);
        System.out.println("  Before: ");
        input.get(context.callString).print(System.out, 4);
        System.out.println("  After: ");
        retval.get(context.callString).print(System.out, 4);
    }
    context.stackPtr = newStackPtr;
    return retval;
}
Also used : HashSet(java.util.HashSet) Set(java.util.Set) BoundedSet(com.jopdesign.dfa.framework.BoundedSetFactory.BoundedSet) LDC(org.apache.bcel.generic.LDC) CallString(com.jopdesign.common.code.CallString) InvokeInstruction(org.apache.bcel.generic.InvokeInstruction) ArrayInstruction(org.apache.bcel.generic.ArrayInstruction) LoadInstruction(org.apache.bcel.generic.LoadInstruction) StoreInstruction(org.apache.bcel.generic.StoreInstruction) Instruction(org.apache.bcel.generic.Instruction) FieldInstruction(org.apache.bcel.generic.FieldInstruction) ReferenceType(org.apache.bcel.generic.ReferenceType) PUTSTATIC(org.apache.bcel.generic.PUTSTATIC) LoadInstruction(org.apache.bcel.generic.LoadInstruction) HashSet(java.util.HashSet) Context(com.jopdesign.dfa.framework.Context) DFATool(com.jopdesign.dfa.DFATool) PUTFIELD(org.apache.bcel.generic.PUTFIELD) AppInfoError(com.jopdesign.common.misc.AppInfoError) ContextMap(com.jopdesign.dfa.framework.ContextMap) CallString(com.jopdesign.common.code.CallString) GETFIELD(org.apache.bcel.generic.GETFIELD) BoundedSet(com.jopdesign.dfa.framework.BoundedSetFactory.BoundedSet) InvokeInstruction(org.apache.bcel.generic.InvokeInstruction) ReferenceType(org.apache.bcel.generic.ReferenceType) Type(org.apache.bcel.generic.Type) AASTORE(org.apache.bcel.generic.AASTORE) MethodInfo(com.jopdesign.common.MethodInfo) GETSTATIC(org.apache.bcel.generic.GETSTATIC) StoreInstruction(org.apache.bcel.generic.StoreInstruction)

Example 2 with BoundedSet

use of com.jopdesign.dfa.framework.BoundedSetFactory.BoundedSet in project jop by jop-devel.

the class SymbolicPointsTo method printResult.

public void printResult(DFATool program) {
    Map<String, String> getFields = new TreeMap<String, String>();
    for (InstructionHandle instr : usedRefs.keySet()) {
        ContextMap<CallString, BoundedSet<SymbolicAddress>> r = usedRefs.get(instr);
        Context c = r.getContext();
        MethodInfo method = c.getMethodInfo();
        if (method == null) {
            throw new AssertionError("Internal Error: No method '" + c.method() + "'");
        }
        LineNumberTable lines = method.getCode().getLineNumberTable();
        int sourceLine = lines.getSourceLine(instr.getPosition());
        for (CallString callString : r.keySet()) {
            System.out.println(c.method() + ":" + sourceLine + ":" + callString + ": " + instr);
            BoundedSet<SymbolicAddress> symAddr = r.get(callString);
            String infoStr;
            if (instr.getInstruction() instanceof GETFIELD) {
                GETFIELD gfInstr = (GETFIELD) instr.getInstruction();
                infoStr = String.format("GETFIELD %s %s %s", symAddr.toString(), gfInstr.getFieldName(c.constPool()), gfInstr.getFieldType(c.constPool()));
            } else if (instr.getInstruction() instanceof ARRAYLENGTH) {
                infoStr = String.format("ARRAYLENGTH %s", symAddr.toString());
            } else if (instr.getInstruction() instanceof ArrayInstruction) {
                ArrayInstruction aInstr = (ArrayInstruction) instr.getInstruction();
                infoStr = String.format("%s %s %s[]", aInstr.getName().toUpperCase(), symAddr.toString(), aInstr.getType(c.constPool()));
            } else {
                infoStr = String.format("%s %s", instr.getInstruction().getName().toUpperCase(), symAddr.toString());
            }
            if (infoStr != null) {
                String infoKey = String.format("%s:%04d:%s", c.method(), sourceLine, callString);
                while (getFields.containsKey(infoKey)) infoKey += "'";
                getFields.put(infoKey, infoStr);
            }
        }
    }
    for (Entry<String, String> entry : getFields.entrySet()) {
        System.out.println(entry.getKey());
        System.out.println("  " + entry.getValue());
    }
}
Also used : Context(com.jopdesign.dfa.framework.Context) ARRAYLENGTH(org.apache.bcel.generic.ARRAYLENGTH) CallString(com.jopdesign.common.code.CallString) TreeMap(java.util.TreeMap) InstructionHandle(org.apache.bcel.generic.InstructionHandle) LineNumberTable(org.apache.bcel.classfile.LineNumberTable) CallString(com.jopdesign.common.code.CallString) BoundedSet(com.jopdesign.dfa.framework.BoundedSetFactory.BoundedSet) GETFIELD(org.apache.bcel.generic.GETFIELD) ArrayInstruction(org.apache.bcel.generic.ArrayInstruction) MethodInfo(com.jopdesign.common.MethodInfo)

Example 3 with BoundedSet

use of com.jopdesign.dfa.framework.BoundedSetFactory.BoundedSet in project jop by jop-devel.

the class SymbolicPointsTo method handleNative.

@SuppressWarnings({ "LiteralAsArgToStringEquals" })
private Map<CallString, SymbolicAddressMap> handleNative(MethodInfo method, Context context, ContextMap<CallString, SymbolicAddressMap> input, ContextMap<CallString, SymbolicAddressMap> retval) {
    String methodId = method.getMemberID().toString(false);
    SymbolicAddressMap in = input.get(context.callString);
    SymbolicAddressMap out;
    int nextStackPtr = context.stackPtr - 1;
    if (methodId.equals("com.jopdesign.sys.Native.rd(I)I") || methodId.equals("com.jopdesign.sys.Native.rdMem(I)I") || methodId.equals("com.jopdesign.sys.Native.rdIntMem(I)I")) {
        out = in.cloneFilterStack(nextStackPtr);
    } else if (methodId.equals("com.jopdesign.sys.Native.wr(II)V") || methodId.equals("com.jopdesign.sys.Native.wrMem(II)V") || methodId.equals("com.jopdesign.sys.Native.wrIntMem(II)V")) {
        out = in.cloneFilterStack(nextStackPtr - 2);
    } else if (methodId.equals("com.jopdesign.sys.Native.toInt(Ljava/lang/Object;)I")) {
        out = in.cloneFilterStack(nextStackPtr);
    } else if (methodId.equals("com.jopdesign.sys.Native.toInt(F)I")) {
        out = in.cloneFilterStack(nextStackPtr);
    } else if (methodId.equals("com.jopdesign.sys.Native.toInt(Ljava/lang/Object;)I")) {
        out = in.cloneFilterStack(nextStackPtr);
    } else if (methodId.equals("com.jopdesign.sys.Native.toInt(Ljava/lang/Object;)I")) {
        out = in.cloneFilterStack(nextStackPtr);
    } else if (methodId.equals("com.jopdesign.sys.Native.toLong(D)J")) {
        out = in.cloneFilterStack(nextStackPtr);
    } else if (methodId.equals("com.jopdesign.sys.Native.toDouble(J)D")) {
        out = in.cloneFilterStack(nextStackPtr);
    } else if (methodId.equals("com.jopdesign.sys.Native.toObject(I)Ljava/lang/Object;") || methodId.equals("com.jopdesign.sys.Native.toIntArray(I)[I")) {
        out = in.cloneFilterStack(nextStackPtr);
        out.putStack(context.stackPtr - 1, bsFactory.top());
    } else if (methodId.equals("com.jopdesign.sys.Native.getSP()I")) {
        out = in.cloneFilterStack(nextStackPtr + 1);
    } else if (methodId.equals("com.jopdesign.sys.Native.getField(II)I")) {
        out = in.cloneFilterStack(nextStackPtr - 1);
    } else if (methodId.equals("com.jopdesign.sys.Native.putField(III)V")) {
        out = in.cloneFilterStack(nextStackPtr - 3);
    } else if (methodId.equals("com.jopdesign.sys.Native.condMove(IIZ)I")) {
        out = in.cloneFilterStack(nextStackPtr - 2);
    } else if (methodId.equals("com.jopdesign.sys.Native.arrayLoad(II)I")) {
        out = in.cloneFilterStack(nextStackPtr - 1);
    } else if (methodId.equals("com.jopdesign.sys.Native.arrayStore(III)V")) {
        out = in.cloneFilterStack(nextStackPtr - 3);
    } else if (methodId.equals("com.jopdesign.sys.Native.condMoveRef(Ljava/lang/Object;Ljava/lang/Object;Z)Ljava/lang/Object;")) {
        out = in.cloneFilterStack(nextStackPtr - 2);
        BoundedSet<SymbolicAddress> joined = in.getStack(context.stackPtr - 3).join(in.getStack(context.stackPtr - 2));
        out.putStack(context.stackPtr - 3, joined);
    } else {
        out = null;
        RuntimeException ex = new RuntimeException("Unknown native method: " + methodId);
        Logger.getLogger(this.getClass()).error(ex);
        throw ex;
    }
    retval.put(context.callString, out);
    return retval;
}
Also used : BoundedSet(com.jopdesign.dfa.framework.BoundedSetFactory.BoundedSet) CallString(com.jopdesign.common.code.CallString)

Aggregations

CallString (com.jopdesign.common.code.CallString)3 BoundedSet (com.jopdesign.dfa.framework.BoundedSetFactory.BoundedSet)3 MethodInfo (com.jopdesign.common.MethodInfo)2 Context (com.jopdesign.dfa.framework.Context)2 ArrayInstruction (org.apache.bcel.generic.ArrayInstruction)2 GETFIELD (org.apache.bcel.generic.GETFIELD)2 AppInfoError (com.jopdesign.common.misc.AppInfoError)1 DFATool (com.jopdesign.dfa.DFATool)1 ContextMap (com.jopdesign.dfa.framework.ContextMap)1 HashSet (java.util.HashSet)1 Set (java.util.Set)1 TreeMap (java.util.TreeMap)1 LineNumberTable (org.apache.bcel.classfile.LineNumberTable)1 AASTORE (org.apache.bcel.generic.AASTORE)1 ARRAYLENGTH (org.apache.bcel.generic.ARRAYLENGTH)1 FieldInstruction (org.apache.bcel.generic.FieldInstruction)1 GETSTATIC (org.apache.bcel.generic.GETSTATIC)1 Instruction (org.apache.bcel.generic.Instruction)1 InstructionHandle (org.apache.bcel.generic.InstructionHandle)1 InvokeInstruction (org.apache.bcel.generic.InvokeInstruction)1