public MethodExceptionAnalysis(
      SootClass c, SootMethod m, Map<SootClass, ClassExceptionAnalysis> cm) {
    method = m;
    soot_class = c;
    class_map = cm;
    body = m.retrieveActiveBody();
    trap_begin_exception_sets = new HashMap<Unit, List<TwoValuePair<Trap, Set<SootClass>>>>();
    trap_end_exception_sets = new HashMap<Unit, List<TwoValuePair<Trap, Set<SootClass>>>>();
    method_exception_set = new HashSet<SootClass>();

    for (Trap t : body.getTraps()) {
      List<TwoValuePair<Trap, Set<SootClass>>> trap_pairs;
      TwoValuePair<Trap, Set<SootClass>> tvp;

      if (trap_begin_exception_sets.containsKey(
          t.getBeginUnit())) { // we assume that if traps have the same begin unit, they must
        // have the same end unit and the same exception set as well
        trap_pairs = trap_begin_exception_sets.get(t.getBeginUnit());
        tvp = new TwoValuePair<Trap, Set<SootClass>>(t, trap_pairs.get(0).w); // use the same set
      } else {
        trap_pairs = new ArrayList<TwoValuePair<Trap, Set<SootClass>>>();
        tvp = new TwoValuePair<Trap, Set<SootClass>>(t, new HashSet<SootClass>());
      }

      trap_pairs.add(tvp);

      trap_begin_exception_sets.put(t.getBeginUnit(), trap_pairs);
      trap_end_exception_sets.put(
          t.getEndUnit(),
          trap_pairs); // May overwrite different list if we don't make the assumption above
    }
  }
Beispiel #2
0
  protected void internalTransform(Body body, String phaseName, Map options) {
    if (Options.v().verbose())
      G.v().out.println("[" + body.getMethod().getName() + "] Tightening trap boundaries...");

    Chain trapChain = body.getTraps();
    Chain unitChain = body.getUnits();
    if (trapChain.size() > 0) {
      ExceptionalUnitGraph graph = new ExceptionalUnitGraph(body);

      for (Iterator trapIt = trapChain.iterator(); trapIt.hasNext(); ) {
        Trap trap = (Trap) trapIt.next();
        Unit firstTrappedUnit = trap.getBeginUnit();
        Unit firstTrappedThrower = null;
        Unit firstUntrappedUnit = trap.getEndUnit();
        Unit lastTrappedUnit = (Unit) unitChain.getPredOf(firstUntrappedUnit);
        Unit lastTrappedThrower = null;
        for (Unit u = firstTrappedUnit;
            u != null && u != firstUntrappedUnit;
            u = (Unit) unitChain.getSuccOf(u)) {
          if (mightThrowTo(graph, u, trap)) {
            firstTrappedThrower = u;
            break;
          }
        }
        if (firstTrappedThrower != null) {
          for (Unit u = lastTrappedUnit; u != null; u = (Unit) unitChain.getPredOf(u)) {
            if (mightThrowTo(graph, u, trap)) {
              lastTrappedThrower = u;
              break;
            }
          }
        }
        if (firstTrappedThrower != null && firstTrappedUnit != firstTrappedThrower) {
          trap.setBeginUnit(firstTrappedThrower);
        }
        if (lastTrappedThrower == null) {
          lastTrappedThrower = firstTrappedUnit;
        }
        if (lastTrappedUnit != lastTrappedThrower) {
          trap.setEndUnit((Unit) unitChain.getSuccOf(lastTrappedThrower));
        }
      }
    }
  }
  void doWeave(
      SootMethod method,
      LocalGeneratorEx lg,
      AdviceApplication adviceappl,
      Residue residue,
      WeavingContext wc) {
    AdviceInliner.v().addShadowMethod(method);
    ShadowPoints shadowpoints = adviceappl.shadowmatch.sp;
    AbstractAdviceDecl advicedecl = adviceappl.advice;

    Body b = method.getActiveBody();
    Chain units = b.getUnits().getNonPatchingChain();

    // end of shadow
    Stmt endshadow = shadowpoints.getEnd();

    NopStmt nop2 = Jimple.v().newNopStmt();
    GotoStmt goto1 = Jimple.v().newGotoStmt(nop2);
    if (advicedecl instanceof CflowSetup) {
      Tagger.tagStmt(goto1, InstructionKindTag.CFLOW_EXIT);
    } else if (advicedecl instanceof PerCflowSetup) {
      Tagger.tagStmt(goto1, InstructionKindTag.PERCFLOW_EXIT);
    } else if (advicedecl instanceof DeclareSoft) {
      Tagger.tagStmt(goto1, InstructionKindTag.EXCEPTION_SOFTENER);
    } else if (advicedecl instanceof DeclareMessage) {
      Tagger.tagStmt(goto1, InstructionKindTag.DECLARE_MESSAGE);
    } else {
      Tagger.tagStmt(goto1, InstructionKindTag.AFTER_THROWING_HANDLER);
    }
    Tagger.tagStmt(goto1, new InstructionSourceTag(advicedecl.sourceId));
    Tagger.tagStmt(goto1, new InstructionShadowTag(adviceappl.shadowmatch.shadowId));
    units.insertBefore(nop2, endshadow);
    units.insertBefore(goto1, nop2);

    // have ...
    //    goto1:      goto nop2;
    //    nop2:       nop;
    //    endshadow:  nop;

    RefType catchType = getCatchType();
    Local exception = lg.generateLocal(catchType, "exception");
    bindException(wc, advicedecl, exception);

    CaughtExceptionRef exceptRef = Jimple.v().newCaughtExceptionRef();
    IdentityStmt idStmt = Jimple.v().newIdentityStmt(exception, exceptRef);
    units.insertAfter(idStmt, goto1);

    ThrowStmt throwStmt = Jimple.v().newThrowStmt(exception);
    throwStmt.addTag(new ThrowCreatedByCompilerTag());

    if (advicedecl instanceof CflowSetup) {
      Tagger.tagStmt(throwStmt, InstructionKindTag.CFLOW_EXIT);
    } else if (advicedecl instanceof PerCflowSetup) {
      Tagger.tagStmt(throwStmt, InstructionKindTag.PERCFLOW_EXIT);
    } else if (advicedecl instanceof DeclareSoft) {
      Tagger.tagStmt(throwStmt, InstructionKindTag.EXCEPTION_SOFTENER);
    } else if (advicedecl instanceof DeclareMessage) {
      Tagger.tagStmt(throwStmt, InstructionKindTag.DECLARE_MESSAGE);
    } else {
      Tagger.tagStmt(throwStmt, InstructionKindTag.AFTER_THROWING_HANDLER);
    }
    Tagger.tagStmt(throwStmt, new InstructionSourceTag(advicedecl.sourceId));
    Tagger.tagStmt(throwStmt, new InstructionShadowTag(adviceappl.shadowmatch.shadowId));

    // store shadow/source tag for this residue in weaving context
    if (advicedecl instanceof CflowSetup) {
      wc.setKindTag(InstructionKindTag.CFLOW_TEST);
    }
    if (advicedecl instanceof PerCflowSetup) {
      wc.setKindTag(InstructionKindTag.CFLOW_TEST);
    }
    wc.setShadowTag(new InstructionShadowTag(adviceappl.shadowmatch.shadowId));
    wc.setSourceTag(new InstructionSourceTag(adviceappl.advice.sourceId));

    Stmt endresidue = residue.codeGen(method, lg, units, idStmt, throwStmt, true, wc);

    // have ...
    //    java.lang.Exception exception;
    //
    //    goto1:      goto nop2;
    //    idStmt:     exception := @caughtexception
    //    nop2:       nop;
    //    endshadow:  nop;

    units.insertAfter(throwStmt, endresidue);

    Chain invokestmts = advicedecl.makeAdviceExecutionStmts(adviceappl, lg, wc);

    for (Iterator stmtlist = invokestmts.iterator(); stmtlist.hasNext(); ) {
      Stmt nextstmt = (Stmt) stmtlist.next();
      units.insertBefore(nextstmt, throwStmt);
    }

    if (method.getName().equals("<clinit>"))
    // have to handle case of ExceptionInInitialzerError
    { //  if (exception instanceof java.lang.ExceptionInIntializerError)
      //     throw (exception);
      debug("Adding extra check in clinit");

      Local isInitError = lg.generateLocal(soot.BooleanType.v(), "isInitError");

      Stmt assignbool =
          Jimple.v()
              .newAssignStmt(
                  isInitError,
                  Jimple.v()
                      .newInstanceOfExpr(
                          exception, RefType.v("java.lang.ExceptionInInitializerError")));

      Stmt ifstmt =
          Jimple.v().newIfStmt(Jimple.v().newNeExpr(isInitError, IntConstant.v(0)), throwStmt);

      //	     ThrowStmt throwInitError = Jimple.v().newThrowStmt(exception);

      //	     units.insertAfter(throwInitError, idStmt);
      units.insertAfter(ifstmt, idStmt);
      units.insertAfter(assignbool, idStmt);
    }

    Stmt beginshadow = shadowpoints.getBegin();
    Stmt begincode = (Stmt) units.getSuccOf(beginshadow);

    // have ...
    //    java.lang.Exception exception;
    //    <AspectType> theAspect;
    //
    //    beginshadow:   nop
    //    begincode:     <some statement>
    //       ....        <stuff in between>
    //    goto1:         goto nop2;
    //    idStmt:        exception := @caughtexception;
    //    assignStmt:    theAspect = new AspectOf();
    //             .... invoke statements ....
    //    throwStmt:     throw exception;
    //    nop2:          nop;
    //    endshadow:     nop;

    Chain traps = b.getTraps();
    Trap t = traps.size() > 0 ? (Trap) traps.getFirst() : null;

    // assume no exception ranges overlap with this one; make sure
    // we go after any that would be enclosed within this one.
    while (t != null
        && (units.follows(t.getBeginUnit(), begincode)
            || (t.getBeginUnit() == begincode && units.follows(idStmt, t.getEndUnit()))))
      t = (Trap) traps.getSuccOf(t);

    Trap newt = Jimple.v().newTrap(catchType.getSootClass(), begincode, idStmt, idStmt);

    if (t == null) traps.addLast(newt);
    else traps.insertBefore(newt, t);

    //  added
    //     catch java.lang.Throwable
    //         from begincode upto idStmt handlewith idStmt

  } // method doWeave
Beispiel #4
0
  @Override
  @SuppressWarnings("rawtypes")
  public void internalTransform(Body body, String phaseName, Map options) {
    final SootMethod method = body.getMethod();

    System.out.println();
    System.out.println(
        method.getDeclaringClass().getName() + " :: " + method.getBytecodeSignature());

    System.out.println("--- locals ---");
    for (Local l : body.getLocals()) System.out.println(" " + l.getName() + " : " + l.getType());

    System.out.println("--- units ---");
    Unit[] units = body.getUnits().toArray(new Unit[0]);
    for (int i = 0; i < units.length; i++) {

      if (units[i].hasTag("StringTag")) {
        String info = ((StringTag) units[i].getTag("StringTag")).getInfo();
        if (info.endsWith("Pre")) System.out.println("\n      " + info);
      }

      System.out.printf("%4d ", i);

      if (units[i] instanceof GotoStmt) {
        System.out.println("goto " + getIndex(units, ((GotoStmt) units[i]).getTarget()));

      } else if (units[i] instanceof IfStmt) {
        System.out.println(
            "if "
                + ((IfStmt) units[i]).getCondition()
                + " goto "
                + getIndex(units, ((IfStmt) units[i]).getTarget()));

      } else if (units[i] instanceof TableSwitchStmt) {
        TableSwitchStmt sw = (TableSwitchStmt) units[i];
        System.out.println("tswitch(" + sw.getKey() + ")");
        final int lowIndex = sw.getLowIndex();
        for (int t = 0; t <= sw.getHighIndex() - lowIndex; t++)
          System.out.println(
              "      case " + (t + lowIndex) + ": goto " + getIndex(units, sw.getTarget(t)));
        System.out.println("      default: goto " + getIndex(units, sw.getDefaultTarget()));

      } else if (units[i] instanceof LookupSwitchStmt) {
        LookupSwitchStmt sw = (LookupSwitchStmt) units[i];
        System.out.println("lswitch(" + sw.getKey() + ")");
        for (int v = 0; v < sw.getTargetCount(); v++)
          System.out.println(
              "      case " + sw.getLookupValue(v) + ": goto " + getIndex(units, sw.getTarget(v)));
        System.out.println("      default: goto " + getIndex(units, sw.getDefaultTarget()));

      } else if (units[i] instanceof InvokeStmt) {
        System.out.println(toString(((InvokeStmt) units[i]).getInvokeExpr()));

      } else if (units[i] instanceof AssignStmt) {
        if (((AssignStmt) units[i]).getRightOp() instanceof InvokeExpr)
          System.out.println(
              ((AssignStmt) units[i]).getLeftOp()
                  + " = "
                  + toString((InvokeExpr) ((AssignStmt) units[i]).getRightOp()));
        else System.out.println(units[i]);

      } else {
        System.out.println(units[i]);
      }

      if (units[i].hasTag("StringTag")) {
        String info = ((StringTag) units[i].getTag("StringTag")).getInfo();

        if (!info.endsWith("Pre")) System.out.println("      " + info);
        if (info.endsWith("After")) System.out.println();
      }
    }

    System.out.println("--- traps ---");
    for (Trap t : body.getTraps())
      System.out.println(
          " ["
              + getIndex(units, t.getBeginUnit())
              + "-"
              + getIndex(units, t.getEndUnit())
              + ") -> ("
              + t.getException()
              + ") -> "
              + getIndex(units, t.getHandlerUnit()));

    System.out.println();
  }