예제 #1
0
  @Override
  public Instruction execute(ThreadInfo th) {
    StackFrame sf = th.getModifiableTopFrame();
    IntegerExpression sym_v1 = (IntegerExpression) sf.getOperandAttr(0);
    IntegerExpression sym_v2 = (IntegerExpression) sf.getOperandAttr(1);
    int v1, v2;

    if (sym_v1 == null && sym_v2 == null)
      return super.execute(th); // we'll still do the concrete execution

    // result is symbolic

    if (sym_v1 == null && sym_v2 != null) {
      v1 = sf.pop();
      v2 = sf.pop();
      if (v1 == 0) return th.createAndThrowException("java.lang.ArithmeticException", "div by 0");
      sf.push(0, false);
      IntegerExpression result = sym_v2._div(v1);
      sf.setOperandAttr(result);
      return getNext(th);
    }

    // div by zero check affects path condition
    // sym_v1 is non-null and should be checked against zero

    ChoiceGenerator<?> cg;
    boolean condition;

    if (!th.isFirstStepInsn()) { // first time around
      cg = new PCChoiceGenerator(2);
      ((PCChoiceGenerator) cg).setOffset(this.position);
      ((PCChoiceGenerator) cg).setMethodName(this.getMethodInfo().getFullName());
      th.getVM().setNextChoiceGenerator(cg);
      return this;
    } else { // this is what really returns results
      cg = th.getVM().getChoiceGenerator();
      assert (cg instanceof PCChoiceGenerator) : "expected PCChoiceGenerator, got: " + cg;
      condition = (Integer) cg.getNextChoice() == 0 ? false : true;
    }

    v1 = sf.pop();
    v2 = sf.pop();
    sf.push(0, false);

    PathCondition pc;
    ChoiceGenerator<?> prev_cg = cg.getPreviousChoiceGeneratorOfType(PCChoiceGenerator.class);

    if (prev_cg == null) pc = new PathCondition();
    else pc = ((PCChoiceGenerator) prev_cg).getCurrentPC();

    assert pc != null;

    if (condition) { // check div by zero
      pc._addDet(Comparator.EQ, sym_v1, 0);
      if (pc.simplify()) { // satisfiable
        ((PCChoiceGenerator) cg).setCurrentPC(pc);

        return th.createAndThrowException("java.lang.ArithmeticException", "div by 0");
      } else {
        th.getVM().getSystemState().setIgnored(true);
        return getNext(th);
      }
    } else {
      pc._addDet(Comparator.NE, sym_v1, 0);
      if (pc.simplify()) { // satisfiable
        ((PCChoiceGenerator) cg).setCurrentPC(pc);

        // set the result
        IntegerExpression result;
        if (sym_v2 != null) result = sym_v2._div(sym_v1);
        else result = sym_v1._div_reverse(v2);

        sf = th.getModifiableTopFrame();
        sf.setOperandAttr(result);
        return getNext(th);

      } else {
        th.getVM().getSystemState().setIgnored(true);
        return getNext(th);
      }
    }
  }
예제 #2
0
  @Override
  public Instruction execute(ThreadInfo ti) {
    // We may need to add the case where we have a smybolic index and a concrete array

    IntegerExpression indexAttr = null;
    ArrayExpression arrayAttr = null;
    StackFrame frame = ti.getModifiableTopFrame();
    int arrayRef = peekArrayRef(ti); // need to be polymorphic, could be LongArrayStore

    if (arrayRef == MJIEnv.NULL) {
      return ti.createAndThrowException("java.lang.NullPointerException");
    }

    // Retrieve the array expression if it was previously in the pathcondition, and store it as an
    // array attr
    PCChoiceGenerator temp_cg =
        (PCChoiceGenerator) ti.getVM().getLastChoiceGeneratorOfType(PCChoiceGenerator.class);
    if (temp_cg != null) {
      if (temp_cg
          .getCurrentPC()
          .arrayExpressions
          .containsKey(ti.getElementInfo(ti.getModifiableTopFrame().peek(2)).toString())) {
        ti.getModifiableTopFrame()
            .setOperandAttr(
                2,
                temp_cg
                    .getCurrentPC()
                    .arrayExpressions
                    .get(ti.getElementInfo(ti.getModifiableTopFrame().peek(2)).toString()));
      }
    }

    // If only the value is symbolic, we use the concrete instruction
    if (peekArrayAttr(ti) == null || !(peekArrayAttr(ti) instanceof ArrayExpression)) {
      // In this case, the array isn't symbolic
      if (peekIndexAttr(ti) == null || !(peekIndexAttr(ti) instanceof IntegerExpression)) {
        return super.execute(ti);
      }
    }

    ChoiceGenerator<?> cg;

    if (!ti.isFirstStepInsn()) { // first time around
      cg = new PCChoiceGenerator(3);
      ((PCChoiceGenerator) cg).setOffset(this.position);
      ((PCChoiceGenerator) cg).setMethodName(this.getMethodInfo().getFullName());
      ti.getVM().setNextChoiceGenerator(cg);
      return this;
    } else { // this is what really returns results
      cg = ti.getVM().getChoiceGenerator();
      assert (cg instanceof PCChoiceGenerator) : "expected PCChoiceGenerator, got: " + cg;
    }

    PathCondition pc;
    ChoiceGenerator<?> prev_cg = cg.getPreviousChoiceGeneratorOfType(PCChoiceGenerator.class);

    if (prev_cg == null) pc = new PathCondition();
    else pc = ((PCChoiceGenerator) prev_cg).getCurrentPC();

    assert pc != null;

    if (peekIndexAttr(ti) == null || !(peekIndexAttr(ti) instanceof IntegerExpression)) {
      int index = ti.getTopFrame().peek(1);
      indexAttr = new IntegerConstant(index);
    } else {
      indexAttr = (IntegerExpression) peekIndexAttr(ti);
    }

    assert (indexAttr != null) : "indexAttr shouldn't be null in FASTORE instruction";

    if (peekArrayAttr(ti) == null || !(peekArrayAttr(ti) instanceof ArrayExpression)) {
      // In this case, the array isn't symbolic
      if (peekIndexAttr(ti) == null || !(peekIndexAttr(ti) instanceof IntegerExpression)) {
        return super.execute(ti);
      } else {
        // We create a symbolic array out of the concrete array
        ElementInfo arrayInfo = ti.getElementInfo(arrayRef);
        arrayAttr = ArrayExpression.create(arrayInfo.toString(), arrayInfo.arrayLength());
        // We add the constraints about all the elements of the array
        for (int i = 0; i < arrayInfo.arrayLength(); i++) {
          float arrValue = arrayInfo.getFloatElement(i);
          pc._addDet(
              Comparator.EQ,
              new SelectExpression(arrayAttr, new IntegerConstant(i)),
              new RealConstant(arrValue));
        }
      }
    } else {
      arrayAttr = (ArrayExpression) peekArrayAttr(ti);
    }
    assert (arrayAttr != null) : "arrayAttr shouldn't be null in FASTORE instruction";

    if ((Integer) cg.getNextChoice() == 1) { // check bounds of the index
      pc._addDet(Comparator.GE, indexAttr, arrayAttr.length);
      if (pc.simplify()) { // satisfiable
        ((PCChoiceGenerator) cg).setCurrentPC(pc);
        return ti.createAndThrowException(
            "java.lang.ArrayIndexOutOfBoundsException", "index greater than array bounds");
      } else {
        ti.getVM().getSystemState().setIgnored(true);
        return getNext(ti);
      }
    } else if ((Integer) cg.getNextChoice() == 2) {
      pc._addDet(Comparator.LT, indexAttr, new IntegerConstant(0));
      if (pc.simplify()) { // satisfiable
        ((PCChoiceGenerator) cg).setCurrentPC(pc);
        return ti.createAndThrowException(
            "java.lang.ArrayIndexOutOfBoundsException", "index smaller than array bounds");
      } else {
        ti.getVM().getSystemState().setIgnored(true);
        return getNext(ti);
      }
    } else {
      pc._addDet(Comparator.LT, indexAttr, arrayAttr.length);
      pc._addDet(Comparator.GE, indexAttr, new IntegerConstant(0));
      if (pc.simplify()) { // satisfiable
        ((PCChoiceGenerator) cg).setCurrentPC(pc);
        RealExpression sym_value = null;
        if (frame.getOperandAttr(0) == null
            || !(frame.getOperandAttr(0) instanceof RealExpression)) {
          float value = frame.popFloat();
          sym_value = new RealConstant(value);
        } else {
          // The value is symbolic.
          sym_value = (RealExpression) frame.getOperandAttr(0);
          frame.popFloat();
        }
        // We create a new arrayAttr, and inherits information from the previous attribute
        ArrayExpression newArrayAttr = new ArrayExpression(arrayAttr);
        frame.pop(2); // We pop the array and the index

        RealStoreExpression se = new RealStoreExpression(arrayAttr, indexAttr, sym_value);
        pc._addDet(Comparator.EQ, se, newArrayAttr);
        pc.arrayExpressions.put(newArrayAttr.getRootName(), newArrayAttr);

        return getNext(ti);
      } else {
        ti.getVM().getSystemState().setIgnored(true);
        return getNext(ti);
      }
    }
  }