@Override public Unit getHandlerNode() { if (trap == null) { return null; } else { return trap.getHandlerUnit(); } }
protected void buildSimpleExceptionalEdges(Map unitToSuccs, Map unitToPreds) { for (Iterator<Trap> trapIt = body.getTraps().iterator(); trapIt.hasNext();) { Trap trap = trapIt.next(); Unit handler = trap.getHandlerUnit(); for (Iterator predIt = ((List) unitToPreds.get(trap.getBeginUnit())).iterator(); predIt.hasNext();) { Unit pred = (Unit) predIt.next(); addEdge(unitToSuccs, unitToPreds, pred, handler); } } } }
private boolean isExceptionHandlerBlock(Block aBlock) { Unit blockHead = aBlock.getHead(); for (Trap trap : mBody.getTraps()) { if (trap.getHandlerUnit() == blockHead) { return true; } } return false; }
private static RefType isHandlerUnit(Chain<Trap> traps, Unit h) { Iterator<Trap> it = traps.iterator(); while (it.hasNext()) { Trap t = (Trap) it.next(); if (t.getHandlerUnit() == h) { return t.getException().getType(); } } return null; }
public boolean checkTraps(Unit u, Body b) { Iterator<Trap> it = b.getTraps().iterator(); while (it.hasNext()) { Trap t = it.next(); if (t.getBeginUnit() == u || t.getEndUnit() == u || t.getHandlerUnit() == u) { return true; } } return false; }
/** * Given a body and a unit handling an exception, returns the list of exception types possibly caught by the handler. */ public static List<RefType> getExceptionTypesOf(Unit u, Body body) { List<RefType> possibleTypes = new ArrayList<RefType>(); for (Trap trap : body.getTraps()) { if (trap.getHandlerUnit() == u) { possibleTypes.add(RefType.v(trap.getException().getName())); } } return possibleTypes; } }
/** * Checks whether all Caught-Exception-References are associated to traps. */ @Override public void validate(Body body, List<ValidationException> exceptions) { Set<Unit> caughtUnits = new HashSet<Unit>(); for (Trap trap : body.getTraps()) { caughtUnits.add(trap.getHandlerUnit()); if (!(trap.getHandlerUnit() instanceof IdentityStmt)) { exceptions.add(new ValidationException(trap, "Trap handler does not start with caught " + "exception reference")); } else { IdentityStmt is = (IdentityStmt) trap.getHandlerUnit(); if (!(is.getRightOp() instanceof CaughtExceptionRef)) { exceptions.add(new ValidationException(trap, "Trap handler does not start with caught " + "exception reference")); } } } for (Unit u : body.getUnits()) { if (u instanceof IdentityStmt) { IdentityStmt id = (IdentityStmt) u; if (id.getRightOp() instanceof CaughtExceptionRef) { if (!caughtUnits.contains(id)) { exceptions.add(new ValidationException(id, "Could not find a corresponding trap using this statement as handler", "Body of method " + body.getMethod().getSignature() + " contains a caught exception reference," + "but not a corresponding trap using this statement as handler")); } } } } }
/** * Exceptional Phi nodes have a huge number of arguments and control flow predecessors by default. Since it is useless * trying to keep the number of arguments and control flow predecessors in synch, we might as well trim out all redundant * arguments and eliminate a huge number of copy statements when we get out of SSA form in the process. **/ public void trimExceptionalPhiNodes() { Set<Unit> handlerUnits = new HashSet<Unit>(); Iterator<Trap> trapsIt = body.getTraps().iterator(); while (trapsIt.hasNext()) { Trap trap = trapsIt.next(); handlerUnits.add(trap.getHandlerUnit()); } for (Block block : cfg) { // trim relevant Phi expressions if (handlerUnits.contains(block.getHead())) { for (Unit unit : block) { // if(!(newPhiNodes.contains(unit))) PhiExpr phi = Shimple.getPhiExpr(unit); if (phi == null) { continue; } trimPhiNode(phi); } } } }
@Override protected Flow getFlow(Unit from, Unit to) { // QND if (to instanceof IdentityUnit) { if (graph instanceof ExceptionalGraph) { ExceptionalGraph<Unit> g = (ExceptionalGraph<Unit>) graph; if (!g.getExceptionalPredsOf(to).isEmpty()) { // look if there is a real exception edge for (ExceptionDest<Unit> exd : g.getExceptionDests(from)) { Trap trap = exd.getTrap(); if (null == trap) { continue; } if (trap.getHandlerUnit() == to) { return Flow.IN; } } } } } return Flow.OUT; }
if (exGraph != null) { for (ExceptionDest ed : exGraph.getExceptionDests(u)) { if (ed.getTrap() != null && ed.getTrap().getHandlerUnit() == succ) { isExceptionalTarget = true;
Trap trap = trapIt.next(); Unit firstTrapped = trap.getBeginUnit(); Unit catcher = trap.getHandlerUnit();
private boolean isRewritable(Trap t) { // ignore traps that already catch their own begin unit if (t.getBeginUnit() == t.getHandlerUnit()) { return false; } // ignore runtime try blocks - these may have weird side-effects do to asynchronous exceptions SootClass exc = t.getException(); if (exc.getName().equals("java.lang.Throwable")) { return false; } do { if (exc.getName().equals("java.lang.RuntimeException")) { return false; } } while (exc.hasSuperclass() && (exc = exc.getSuperclass()) != null); return true; } }
if (trapCoversUnit(b, t3, t1.getHandlerUnit()) && t3.getHandlerUnit() == t2.getHandlerUnit()) { } else if (trapCoversUnit(b, t3, t2.getHandlerUnit()) && t3.getHandlerUnit() == t1.getHandlerUnit()) {
public Trap newTrap(Trap trap) { return new GTrap(trap.getException(), trap.getBeginUnit(), trap.getEndUnit(), trap.getHandlerUnit()); }
/** * Method to compute the edges corresponding to exceptional control flow. * * @param unitToSuccs * A <code>Map</code> from {@link Unit}s to {@link List}s of <code>Unit</code>s. This is an “out * parameter”; <code>buildExceptionalEdges</code> will add a mapping for every <code>Unit</code> within the * scope of one or more {@link Trap}s to a <code>List</code> of the handler units of those <code>Trap</code>s. * * @param unitToPreds * A <code>Map</code> from <code>Unit</code>s to <code>List</code>s of <code>Unit</code>s. This is an “out * parameter”; <code>buildExceptionalEdges</code> will add a mapping for every <code>Trap</code> handler to * all the <code>Unit</code>s within the scope of that <code>Trap</code>. */ protected void buildExceptionalEdges(Map<Unit, List<Unit>> unitToSuccs, Map<Unit, List<Unit>> unitToPreds) { for (Trap trap : body.getTraps()) { Unit first = trap.getBeginUnit(); Unit last = unitChain.getPredOf(trap.getEndUnit()); Unit catcher = trap.getHandlerUnit(); for (Iterator<Unit> unitIt = unitChain.iterator(first, last); unitIt.hasNext();) { Unit trapped = unitIt.next(); addEdge(unitToSuccs, unitToPreds, trapped, catcher); } } } }
@Override /** Verifies that the begin, end and handler units of each trap are in this body. */ public void validate(Body body, List<ValidationException> exception) { PatchingChain<Unit> units = body.getUnits(); for (Trap t : body.getTraps()) { if (!units.contains(t.getBeginUnit())) { exception.add(new ValidationException(t.getBeginUnit(), "begin not in chain" + " in " + body.getMethod())); } if (!units.contains(t.getEndUnit())) { exception.add(new ValidationException(t.getEndUnit(), "end not in chain" + " in " + body.getMethod())); } if (!units.contains(t.getHandlerUnit())) { exception.add(new ValidationException(t.getHandlerUnit(), "handler not in chain" + " in " + body.getMethod())); } } }
public void redirectTraps(Body b, Unit oldUnit, Unit newUnit) { Chain<Trap> traps = b.getTraps(); for (Trap trap : traps) { if (trap.getHandlerUnit() == oldUnit) { trap.setHandlerUnit(newUnit); } if (trap.getBeginUnit() == oldUnit) { trap.setBeginUnit(newUnit); } if (trap.getEndUnit() == oldUnit) { trap.setEndUnit(newUnit); } } }
private void fixJumps(Unit from, Unit to, Chain<Trap> t) { from.redirectJumpsToThisTo(to); for (Trap trap : t) { if (trap.getBeginUnit() == from) { trap.setBeginUnit(to); } if (trap.getEndUnit() == from) { trap.setEndUnit(to); } if (trap.getHandlerUnit() == from) { trap.setHandlerUnit(to); } } } }
public static void updateTraps(Unit oldu, Unit newu, Chain<Trap> traps) { int size = traps.size(); if (size == 0) { return; } Trap t = traps.getFirst(); do { if (t.getBeginUnit() == oldu) { t.setBeginUnit(newu); } if (t.getEndUnit() == oldu) { t.setEndUnit(newu); } if (t.getHandlerUnit() == oldu) { t.setHandlerUnit(newu); } } while ((--size > 0) && (t = traps.getSuccOf(t)) != null); }
@Override protected void internalTransform(Body b, String phaseName, Map<String, String> options) { for (Trap t : b.getTraps()) { // If the first statement already catches the exception, we're fine if (isCaughtExceptionRef(t.getHandlerUnit())) { continue; } // Add the exception reference Local l = new LocalGenerator(b).generateLocal(t.getException().getType()); Stmt caughtStmt = Jimple.v().newIdentityStmt(l, Jimple.v().newCaughtExceptionRef()); b.getUnits().add(caughtStmt); b.getUnits().add(Jimple.v().newGotoStmt(t.getHandlerUnit())); t.setHandlerUnit(caughtStmt); } }